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

Jim*_*son 2 java upload tomcat spring-mvc

我已经阅读了文章"使用Spring MVC和注释配置进行文件上传"(http://www.raistudies.com/spring/spring-mvc/file-upload-spring-mvc-annotation)

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

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

但是,当我上传一个大于3M字节的大文件时,MaxUploadSizeExceededException将被"捕获"两次,然后浏览器和服务器之间的 连接将被破坏.浏览器报告ERR_CONNECTION_RESET错误并且没有显示错误信息(或页面),它看起来像某人的电缆连接到我的电脑.

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

我试过使用Spring 4.1.4,问题仍然存在.

顺便说一下,文件上传的懒惰模式在我的情况下是不合适的.因此,当需要捕获MaxUploadSizeExceededException时,我需要立即向用户报告结果.这就是我的预期.

如何解决上传大文件导致的"断线"问题?

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

    @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
    }
}
Run Code Online (Sandbox Code Playgroud)

Jim*_*son 6

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

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