2016-01-06 115 views
15

有时当我尝试上传一个文件在我的远程VPS我得到这个例外(以60%的上传proccess停止)上传文件停止与意外EOF读取插座异常

06-Jan-2016 11:59:36.801 SEVERE [http-nio-54000-exec-9] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Request processing failed; 
nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; 
nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket] 
with root cause 
java.io.EOFException: Unexpected EOF read on the socket 

Google Chrome的connextion丢失,如服务器关闭,我得到ERR_CONNECTION_ABORTED

我Spring MVC中上传文件中像这样

public void save_file(MultipartFile upfile , String path){ 

     try { 

      File fichier = new File(path) ; 
      byte[] bytes = upfile.getBytes(); 
      BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier)); 
      stream.write(bytes); 
      stream.close(); 
      System.out.println("You successfully uploaded " + upfile.getOriginalFilename() + "!"); 

     } catch (Exception e) { 
      System.out.println("You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage()); ; 
     } 

} 

我的控制器:

@RequestMapping(value = "/administration/upload", method = RequestMethod.POST) 
public String Upload_AO_journal(
     @ModelAttribute UploadForm uploadForm, 
       Model map , HttpServletRequest request, HttpSession session) throws ParseException, UnsupportedEncodingException { 

我的豆

public class UploadForm { 

    ... 
    public MultipartFile scan; 

那么如何才能解决这个问题?

+0

它对所有文件大小都失败,还是小文件成功?你能分享一下将这个请求映射到这个方法的Spring特定代码吗? – tdimmig

+0

@tdimmig有时它会失败,有时它的大小相同,它是okey!我更新我的问题。 – Youssef

+1

看看这个答案可以帮助你:http://stackoverflow.com/a/18543887/4056187 – robert

回答

4

你试过流吗?

JSP代码:

<form method="POST" onsubmit="" ACTION="url?${_csrf.parameterName}=${_csrf.token}" ENCTYPE="multipart/form-data">

控制器:

@RequestMapping(
     value = "url", method = RequestMethod.POST 
) 
public void uploadFile(
     @RequestParam("file") MultipartFile file 
) throws IOException { 

InputStream input = upfile.getInputStream(); 
Path path = Paths.get(path);//check path 
OutputStream output = Files.newOutputStream(path); 
IOUtils.copy(in, out); //org.apache.commons.io.IOUtils or you can create IOUtils.copy 

} 

所有与春天4.0春季安全为我工作。

其次,你应该检查http连接是否超时。 Chrome不支持该配置。所以你可以使用Firefox,并按照这里http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html

+0

文件的apache api比文件的默认java api更安全吗? – Youssef

+0

我用它,只是因为它干净而且经过测试。我不认为它更安全。 – ahll

1

不确定upfile上的getBytes()方法。更合适的方法是使用InputStream来管理任何大小的文件,并在必要时缓冲。就像:

public void save_file(MultipartFile upfile , String path){ 

    try { 
     File fichier = new File(path) ; 
     BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier)); 
     InputStream is = upfile.getInputStream(); 
     byte [] bytes = new byte[1024]; 
     int sizeRead; 
     while ((sizeRead = is.read(bytes,0, 1024)) > 0) { 
      stream.write(bytes, 0, sizeRead); 
     } 
     stream.flush(); 
     stream.close(); 
     System.out.println("You successfully uploaded " + upfile.getOriginalFilename() + "!"); 

    } catch (Exception e) { 
     System.out.println("You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage()); ; 
    } 

} 
+0

为什么'新字节[1024]'?大小将被分开1024? – Youssef

+0

你可以将它做成任何你需要的大小,1024是1K,并且通常是下载最高性能的大小。你试过了吗? –

+0

尚未当我回家我会尝试 – Youssef

1

我有类似的问题,问题是当您上传文件,你正在使用多部分形式的POST请求。你可以阅读约MIME

MIME-Version: 1.0 
Content-Type: multipart/mixed; boundary=frontier 

This is a message with multiple parts in MIME format. 
--frontier 
Content-Type: text/plain 

This is the body of the message. 
--frontier 
Content-Type: application/octet-stream 
Content-Transfer-Encoding: base64 

PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg 
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg== 
--frontier-- 

发行基本上我是从请求多了元信息部分,正文部分和实际的文件编码,我相信用base64。每个部分都是按边界分开的。如果您没有设置此边界(在上面的示例中称为“边界”),则服务器开始正确地读取文件,但不知道它结束的位置,直到达到EOF并返回有关意外EOF的错误,因为它没有找到所需的边界。

您的代码存在的问题是,您正在将文件写入ByteOutputStream,当将文件从服务器返回给用户而非其他方式时,此文件适用。服务器期望使用某些标准的预定义格式设置此多部分请求。使用Apache Commons HttpClient库,可为您执行所有此请求的格式化和边界设置。如果你使用Maven那么this link

File f = new File("/path/fileToUpload.txt"); 
PostMethod filePost = new PostMethod("http://host/some_path"); 
Part[] parts = { 
    new StringPart("param_name", "value"), 
    new FilePart(f.getName(), f) 
}; 
filePost.setRequestEntity(
    new MultipartRequestEntity(parts, filePost.getParams()) 
); 
HttpClient client = new HttpClient(); 
int status = client.executeMethod(filePost); 

免责声明:代码是不是我这是例如,从Apache website for multipart request

+0

OP是使用浏览器上传,没有客户端代码? – Michal

+0

那么从他的问题,我明白他是从春季客户端上传,因为他说:“我上传这样的春天mvc文件”,这就是为什么我假设他从客户端上传 – MichaelDD

+0

我想他的意思就像'进'。他在客户端使用谷歌浏览器进行上传,并在服务器端使用Spring MVC。 – Michal

1

出现此问题的原因您关闭流,直到流写入全部数据。

错误方式:

stream.write(bytes); 
stream.close(); 

正确方法:

try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier))) 
{ 
    stream.write(data); 
} 

整个数据写入后,应关闭流。

+0

当然,stream.close()应该放到finally块中。 – ahll