Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am considerably new with Spring, and I want to have a multipart form and handle the MaxUploadSizeExceededException exception in order to show an error message in the jsp. The main problem I have is the ModelAndView Object in the class MaxUploadSizeLimitExceededExceptionResolver, that I don't know how to use it for such objective previously explained.

Files that I have: 1) Model class UploadItem.java. 2) View form UploadForm.jsp. 3) Controller Uploadcontroller.java. 4) Class MaxUploadSizeLimitExceededExceptionResolver.java to handle the exception Uploadcontroller

1) Model UploadItem

public class UploadItem {
    private String name;
    private CommonsMultipartFile fileData;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public CommonsMultipartFile getFileData() {
        return fileData;
    }
    public void setFileData(CommonsMultipartFile fileData) {
        this.fileData = fileData;
    }
}

2) View form UploadForm.jsp

<html>
    <head>
        <META http-equiv="Content-Type" content="text/html;charset=UTF-8">
        <title>Upload form</title>
    </head>
    <body>
        <form:form modelAttribute="uploadItem" method="post" enctype="multipart/form-data">
            <fieldset>
                <legend>Upload Fields</legend>
                <p>
                    <form:label for="name" path="name">Name</form:label><br/>
                    <form:input path="name"/>
                </p>
                <p>
                    <form:label for="fileData" path="fileData">File</form:label><br/>
                    <form:input path="fileData" type="file"/>
                </p>
                <p>
                    <input type="submit" />
                </p>
            </fieldset>
        </form:form>
    </body>
</html>

3) Controller Uploadcontroller

public class Uploadcontroller {
    @RequestMapping(method = RequestMethod.GET)
    public String getUploadForm(Model model) {
        model.addAttribute(new UploadItem());
        return "upload/uploadForm";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String create(HttpServletRequest request, UploadItem uploadItem,
            BindingResult result, Exception exception) {
        if (result.hasErrors()) {
            // logger.info("create upload");
            for (ObjectError error : result.getAllErrors()) {
                System.err.println("Error: " + error.getCode() + " - "
                        + error.getDefaultMessage());
            }
            return "upload/uploadForm";
        }

        System.err.println("Test upload: " + uploadItem.getName());
        System.err.println("Test upload: "
                + uploadItem.getFileData().getOriginalFilename());

        // TODO redirect this
        return "/home";
    }
}

4) Component to handle the exception Uploadcontroller

@Component
public class MaxUploadSizeLimitExceededExceptionResolver extends
        SimpleMappingExceptionResolver {
    private static final Logger logger = LoggerFactory
            .getLogger(HomeController.class);

    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception exception) {
        Map<String, Object> model = new HashMap<String, Object>();
        logger.info("getUploadForm at the beggining");
        ModelAndView modelView = new ModelAndView();
        if (exception instanceof MaxUploadSizeExceededException)
        {
            model.put("errors", exception.getMessage());
            modelView.addObject("errors", exception.getMessage());
            logger.info("getUploadForm: MaxUploadSizeExceededException" );
        } else
        {
            model.put("errors", "Unexpected error: " + exception.getMessage());
            modelView.addObject("errors", "Unexpected error: " +exception.getMessage());
        }
        logger.info("getUploadForm at the end" );        
        model.put("uploadedFile", new UploadItem());
        modelView.addObject(new UploadItem());//("uploadedFile", new UploadItem());
        modelView.setViewName("/upload/uploadForm");
        return modelView;
    }
}

Edit to add more details: Actually, the problem is in another direction. The size of my maxUploadSize file was set to 1MB, but I was trying to do tests with files bigger than 3 MB. When I try with a file until 2 MB maximum is working fine. The problem is that I get a ERR_CONNECTION_RESET and it seems something related to Tomcat, a config of maxSwallowSize --> stackoverflow.com/questions/29113262/… I will continue researching and keep this thread updated.


New information. I have tried with Tomcat 7.0.61 and the error is ERR_CONNECTION_ABORTED I have tried with Tomcat 6.0.43 and there is no error!

like image 888
Weslor Avatar asked Mar 17 '23 09:03

Weslor


1 Answers

After investigating, the problem was due to Tomcat.
In the version 7.0.55 was introduced the property maxSwallowSize set by default to 2MB. This made Tomcat to abort the upload request. By setting this attribute to another value the problem is solved (I changed it to -1, please do not do that in your PRD environment as Tomcat will really try to get a X MB file to upload). I did this by adding in my Tomcat server file ${tomcat_dir}/conf/server.xml in my connector property the attribute maxSwallowSize

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

You need to restart Tomcat so it takes this configuration, if does not work, delete the server and add it again.

like image 154
Weslor Avatar answered Apr 06 '23 00:04

Weslor