tomcat下的一个文件上传异常

昨天晚上发现了一个很奇怪的事情,上传大文件的时候服务器没有任何响应,看了下请求体:
QQ截图20161013134039.png

有provisional headers are shown的警告,google了下provisional headers are shown这个东西,没有什么头绪,无奈之下debug了下,发现确实进入方法了,奇怪的是不止一次调用了javax.servlet.http.HttpServlet.service这个方法,这意味着客户端发起的一个请求,被服务器端处理了多次,也就是说客户端的一次请求,返回了多次结果。继续google spring  upload provisional headers are shown,发现了这么一篇文章:http://blog.csdn.net/liudongdong0909/article/details/52236051#t6大致看了下,遇到的问题应该是一致的,由于文件过大MaxUploadSizeExceededException被抛出,但奇怪的是抛出异常后并没有停止处理,而是看起来有一个retry的过程。上面的文章中还提到了这可能是tomcat的一个bug,这点不敢苟同,文章中明确提到了

apache-tomcat-7.0.67 (不可用)
apache-tomcat-7.0.39 (可用)
apache-tomcat-7.0.70 (可用)
我自己用的tomcat 8.5.4同样存在这个问题,按理应该不会在高低版本中出现bug反复的问题。但这提供了一个思路,tomcat在上传文件过程中,抛出异常之后确实重置了链接,于是继续google:tomcat file upload connection reset,此时终于发现了答案:

http://stackoverflow.com/questions/31605129/spring-file-upload-with-multipart-resolver-causes-connection-reset-when-file-is

I finally have a solution ! The problem was not linked with Spring but with Tomcat and its connector's parameter "maxSwallowSize". Tomcat's explanations for this parameter : "The maximum number of request body bytes (excluding transfer encoding overhead) that will be swallowed by Tomcat for an aborted upload. An aborted upload is when Tomcat knows that the request body is going to be ignored but the client still sends it. If Tomcat does not swallow the body the client is unlikely to see the response. If not specified the default of 2097152 (2 megabytes) will be used. A value of less than zero indicates that no limit should be enforced." So after upping the limit, I could catch the exception and make a redirection with an error message. The problem now is to find the better value for the maxSwallowSize but it's much more easier than my previous problem. Thanks for those who were trying to help !

回到tomcat的server.xml文件,在connector节点增加maxSwallowSize属性,设定该值为-1(应该是没有限制的意思):

<Connector connectionTimeout="20000" maxSwallowSize="-1" port="80" protocol="HTTP/1.1" redirectPort="8443"/>

此时再次上传大文件,终于返回了预期的结果。
上面的文章中还提到了用拦截器来处理这个问题,感觉治标不治本,倒不如直接设置maxUploadSize为-1,再做进一步判断。还有文章中提到的tomcat 7.0.39确实没有这个问题。