Could not upload a large file to the server using Spring MVC?

advertisements

This question already has an answer here:

  • Uploading files in Spring with Tomcat related to the maximum size allowed 1 answer

I've read the article "File upload using Spring MVC and annotation configuration" (http://www.raistudies.com/spring/spring-mvc/file-upload-spring-mvc-annotation)

I really learned some useful things from it and thanks for this article!

It works fine in Tomcat-8.0.20 when I upload a small file.

But , when I upload a large file which is larger than 3M bytes, the MaxUploadSizeExceededException would have been catched "twice" , then the connection between browser and server would be broken. The browser reports an ERR_CONNECTION_RESET error and no error info(or page) is shown, it just looks like the cable to my computer is pulled out by someone.

My system environment is : JRE1.8+Tomcat-8.0.20+WAR_package and my tomcat is a brand new clean tomcat in a new folder , which only has this WAR in it.

I tried by using Spring 4.1.4 , the problem still remains.

By the way ,the lazy mode of file-uploading is not suitable in my case. So I need to report result to user immediately when MaxUploadSizeExceededException has been catched. And this is what I expected.

How to resolve this "disconnection" problem caused by uploading large file ?

Thanks a lot and best regards !

    @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
    }
}


I've confirmed that the problem I met is a mechanism of Tomcat7/8 for an aborted upload request. A new attribute "maxSwallowSize" is the key to deal this situation. It should happen when you upload a file which is larger than 2M.

Because the 2M is the default value of this new attribute . Tomcat7/8 can't swallow the rest file bytes which is being uploaded from browser, so it simply dissconnect the connection. Please visit http://tomcat.apache.org/tomcat-8.0-doc/config/http.html and search for "maxSwallowSize".