无法使用 Spring MVC 将大文件上传到服务器?

Could not upload large file to server by using Spring MVC?

我已阅读文章 "File upload using Spring MVC and annotation configuration" (http://www.raistudies.com/spring/spring-mvc/file-upload-spring-mvc-annotation)

我真的从中学到了一些有用的东西,感谢这篇文章!

当我上传一个小文件时,它在 Tomcat-8.0.20 中工作正常。

但是,当我上传一个大于 3M 字节的大文件时,MaxUploadSizeExceededException 会被捕获 "twice" ,然后 浏览器和服务器之间的连接就会中断。浏览器报告 ERR_CONNECTION_RESET 错误,但没有显示错误信息(或页面),看起来像是有人拔掉了我电脑的电缆。

我的系统环境是: JRE1.8+Tomcat-8.0.20+WAR_package 我的 tomcat 是一个全新的干净 tomcat 在一个新文件夹中,其中只有这个 WAR。

我用Spring 4.1.4试过了,问题依旧。

顺便说一句,文件上传的惰性模式不适合我的情况。所以我需要在捕获到 MaxUploadSizeExceededException 时立即向用户报告结果。 这就是我所期望的。

如何解决上传大文件导致的这个"disconnection"问题?

非常感谢和最诚挚的问候!

    @Controller
    @RequestMapping(value="/FileUploadForm.htm")
    public class UploadFormController implements HandlerExceptionResolver
    {//this is the Exception Handler and Controller class
        @RequestMapping(method=RequestMethod.GET)
    public String showForm(ModelMap model){
        UploadForm form = new UploadForm();
        model.addAttribute("FORM", form);
        return "FileUploadForm";
    }

    @RequestMapping(method=RequestMethod.POST)
    public String processForm(@ModelAttribute(value="FORM") UploadForm form,BindingResult result){
        if(!result.hasErrors()){
            FileOutputStream outputStream = null;
            String filePath = System.getProperty("java.io.tmpdir") + "/" + form.getFile().getOriginalFilename();
            try {
                outputStream = new FileOutputStream(new File(filePath));
                outputStream.write(form.getFile().getFileItem().get());
                outputStream.close();
            } catch (Exception e) {
                System.out.println("Error while saving file");
                return "FileUploadForm";
            }
            return "success";
        }else{
            return "FileUploadForm";
        }
    }

//MaxUploadSizeExceededException can be catched here.....but twice..
//then some weird happend, the connection between browser and server is broken...
    @Override
    public ModelAndView resolveException(HttpServletRequest arg0,
    HttpServletResponse arg1, Object arg2, Exception exception) {
        Map<Object, Object> model = new HashMap<Object, Object>();
        if (exception instanceof MaxUploadSizeExceededException){
            model.put("errors", "File size should be less then "+
            ((MaxUploadSizeExceededException)exception).getMaxUploadSize()+" byte.");
        } else{
            model.put("errors", "Unexpected error: " + exception.getMessage());
        }
        model.put("FORM", new UploadForm());
        return new ModelAndView("/FileUploadForm", (Map) model);//the programme can run to this line and return a ModelAndView object normally
    }
}

更改 CommonsMultipartResolver 配置以使用更大的上传大小。例如,以下行会将最大上传大小设置为 100MB。

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="100000000"/>
</bean>

如果您在浏览器和 Tomcat 之间使用网络服务器,请务必同时更改网络服务器上的上传大小和连接超时,否则请求可能会在到达 [=16= 之前超时].

我已经确认我遇到的问题是 Tomcat7/8 中止上传请求的机制。一个新的属性 "maxSwallowSize" 是处理这种情况的关键。当您上传大于 2M 的文件时应该会发生这种情况。

因为2M是这个新属性的默认值。 Tomcat7/8 无法吞下从浏览器上传的剩余文件字节,所以它只是断开连接。请访问 http://tomcat.apache.org/tomcat-8.0-doc/config/http.html 并搜索 "maxSwallowSize"。