Java 上传文件停止并在套接字异常上读取意外 EOF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34634455/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:51:59  来源:igfitidea点击:

Upload file stop with Unexpected EOF read on the socket Exception

javaspringspring-mvctomcat

提问by Youssef

Sometime when I try to upload a file on my remote vps i get this exception (the upload proccess stop in 60%)

有时当我尝试在我的远程 vps 上上传文件时,我收到此异常(上传过程停止在 60%)

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

and in Google Chromethe connextion is lost like the server is down, i get ERR_CONNECTION_ABORTED

并且在Google Chrome连接丢失时就像服务器关闭一样,我明白了ERR_CONNECTION_ABORTED

i upload file like this in spring mvc

我在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() ); ;
        }

}

my controller :

我的控制器:

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

my bean

我的豆子

public class UploadForm {

    ...
    public MultipartFile scan;

So how can solve this problem ?

那么如何解决这个问题呢?

采纳答案by ahll

Have you tried stream?

你试过流吗?

Jsp code:

JS代码:

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

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

Controller:

控制器:

 @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

}

All that worked for me with spring 4.0 and spring security.

所有这些对我来说都适用于 spring 4.0 和 spring 安全。

Secondly, you should check if the http connection is timeout. Chrome does not support that configuration. So you can use firefox and follow here http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html.

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

回答by Mike Murphy

Not sure about the getBytes() method on the upfile. A more suitable approach would be to use the InputStream which will manage any size file and will buffer when necessary. Something like:

不确定上传文件中的 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() ); ;
    }

}

回答by MichaelDD

I had similar issues and problem is when you are uploading file you are using Multipart Form POST Request. You can read about MIME.

我有类似的问题,问题是当您上传文件时,您正在使用 Multipart Form POST Request。您可以阅读有关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--

Basically issue I had was that multipart from request has meta information part, text part and actual file encoded I believe in base64. Each of this parts are split by boundary. If you don't set up this boundary (in example above it's called "frontier") correctly server starts reading the file but doesn't know where it ends until it reaches EOF and returns error about unexpected EOF because it didn't found required boundaries.

基本上我遇到的问题是来自请求的多部分具有元信息部分,文本部分和实际文件编码我相信 base64。每个部分都按边界分割。如果你没有设置这个边界(在上面的例子中它被称为“前沿”)正确的服务器开始读取文件,但不知道它在哪里结束,直到它到达 EOF 并返回关于意外 EOF 的错误,因为它没有发现需要边界。

Problem with your code is that you are writing file into ByteOutputStream which is suitable when returning file from server to the user not other way around. Server is expecting this Multipart request with some standard predefined formatting. Use Apache Commons HttpClientlibrary that does all this request formating and boundary setting for you. If you use Maven then this link.

您的代码的问题在于您正在将文件写入 ByteOutputStream,这适用于将文件从服务器返回给用户而不是其他方式。服务器期望此 Multipart 请求具有一些标准的预定义格式。使用Apache Commons HttpClient库为您完成所有这些请求格式和边界设置。如果您使用 Maven,则此链接.

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);

Disclaimer: code is not mine it's example from Apache website for multipart request

免责声明:代码不是我的,它是来自Apache 网站的多部分请求示例

回答by eg04lt3r

This issue appears because you close stream until stream write whole data.

出现此问题是因为您关闭流直到流写入整个数据。

Wrong way:

错误的方法:

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

Right way:

正确的方法:

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

You should close your stream after whole data is written.

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