【问题标题】:Unexpected EOF read on the socket during file upload with Spring Boot 2.0使用 Spring Boot 2.0 上传文件期间在套接字上读取意外的 EOF
【发布时间】:2018-11-22 08:49:29
【问题描述】:

我正在开发 webapp,它在后端使用 Spring Boot 2.0。 对于一些用户,我看到了这种错误:

Failed to parse multipart servlet request; nested exception is 
java.io.IOException: 
org.apache.tomcat.util.http.fileupload.FileUploadBase
$IOFileUploadException: Processing of multipart/form-data request 
failed. Unexpected EOF read on the socket]
org.springframework.web.multipart.MultipartException: Failed to parse 
multipart servlet request; nested exception is java.io.IOException: 
org.apache.tomcat.util.http.fileupload.FileUploadBase
$IOFileUploadException: Processing of multipart/form-data request 
failed. Unexpected EOF read on the socket at 
org.springframework.web.multipart.support.
StandardMultipartHttpServletRequest.
handleParseFailure(StandardMultipartHttpServletRequest.java:122) at 
org.springframework.web.multipart.support.
StandardMultipartHttpServletRequest.
parseRequest(StandardMultipartHttpServletRequest.java:113) at 
org.springframework.web.multipart.support.
StandardMultipartHttpServletRequest.<init 
(StandardMultipartHttpServletRequest.java:86) at 
org.springframework.web.multipart.support.
StandardServletMultipartResolver.
resolveMultipart(StandardServletMultipartResolver.java:93) at 
org.springframework.web.servlet.DispatcherServlet.
checkMultipart(DispatcherServlet.java:1128) at 
org.springframework.web.servlet.DispatcherServlet.
doDispatch(DispatcherServlet.java:960) at 
org.springframework.web.servlet.DispatcherServlet.
doService(DispatcherServlet.java:925)...

你能帮我理解这个问题的根源吗?我在服务器上使用这段代码,看起来不错:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseEntity<String> upload(HttpSession session, 
MultipartHttpServletRequest request) {

MultipartFile multipartFile = request.getFiles("file");
try (InputStream inputStream = multipartFile.getInputStream()) {
    //logic ...
}

}

正如我从日志中看到的,请求甚至不调用服务器端点并且在从 UI 端发送数据时失败。好像是网络问题?

另一个奇怪的事情是,这种错误是随机发生的。仅适用于约 2-4% 的用户请求。即使有上传问题的用户尝试再上传几次,通常也可以正常工作

感谢您的任何回答!

【问题讨论】:

  • 网络故障?

标签: java spring sockets spring-boot tomcat


【解决方案1】:

我在使用 Spring Boot 1.5.14.RELEASE 时遇到了同样的问题。

我设法通过在 Chrome 上使用自定义限制 (20KB/s) 模式重现了该问题。当我上传一张大图 (8MB) 时,我会在 30 秒后超时。

请注意,我正在使用 Dropbox 通过 ajax 进行上传。

我调查了一下,发现 Tomcat Connector 有一个异步请求超时的默认值:

/**
 * Default timeout for asynchronous requests (ms).
 */
protected long asyncTimeout = 30000;

我尝试使用 Spring Boot 提供的属性来增加此限制:

# SPRING MVC (WebMvcProperties)
spring.mvc.async.request-timeout= # Amount of time before asynchronous request handling times out.

不幸的是,就我而言,这不起作用。所以我尝试以编程方式配置超时:

@Configuration
public class ServerConfiguration {

  @Bean
  public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
    factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

      @Override
      public void customize(Connector connector) {
        connector.setAsyncTimeout(60000);
        connector.getExecutorName();
      }
    });
    return factory;
  }

}

这不起作用,但我很确定这是问题所在。我看到其他人以这种方式配置了连接器超时,并且对他们有用...

我仍然不知道为什么在我的情况下仍然使用默认值。 试试看,告诉我结果如何。

更新

我知道发生了什么。事实证明,Dropzone 本身也有超时。

https://www.dropzonejs.com/#config-timeout

我将它设置为我想要的值,一切正常。

Spring boot 正在设置属性的值:

spring.mvc.async.request-timeout= # Amount of time before asynchronous request handling times out.

完美。

【讨论】:

    猜你喜欢
    • 2016-04-10
    • 2014-06-15
    • 2018-10-17
    • 2020-02-23
    • 2019-05-05
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    相关资源
    最近更新 更多