Search code examples
spring-mvcfile-uploadexceptionapache-commons-fileupload

Using Spring 3 @ExceptionHandler with commons FileUpload and SizeLimitExceededException/MaxUploadSizeExceededException


I am having trouble with catching and gracefully handling commons fileupload's FileUploadBase.SizeLimitExceededException or spring's MaxUploadSizeExceededException when uploading large files.

From what I can tell these exceptions are thrown during data binding, before the controller is actually reached, therefore resulting in a 500 and no calling of the exception handler method. Has anyone come across this before, and what is the best way for handling these exceptions properly?


Solution

  • thanks to thetoolman for this simple solution. I extended it a bit. I wanted to leave the file handling untouched and transport the Exception to the Controller.

    package myCompany; 
    
    public class DropOversizeFilesMultipartResolver extends CommonsMultipartResolver {
    
        /**
         * Parse the given servlet request, resolving its multipart elements.
         * 
         * Thanks Alexander Semenov @ http://forum.springsource.org/showthread.php?62586
         * 
         * @param request
         *            the request to parse
         * @return the parsing result
         */
        @Override
        protected MultipartParsingResult parseRequest(final HttpServletRequest request) {
    
            String encoding = determineEncoding(request);
            FileUpload fileUpload = prepareFileUpload(encoding);
    
            List fileItems;
    
            try {
                fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
            } catch (FileUploadBase.SizeLimitExceededException ex) {
                request.setAttribute(EXCEPTION_KEY, ex);
                fileItems = Collections.EMPTY_LIST;
            } catch (FileUploadException ex) {
                throw new MultipartException("Could not parse multipart servlet request", ex);
            }
    
            return parseFileItems(fileItems, encoding);
        }
    }
    

    and in the controller

      @InitBinder("fileForm")
      protected void initBinderDesignForm(WebDataBinder binder) {
        binder.setValidator(new FileFormValidator());
      }
    
        @RequestMapping(value = "/my/mapping", method = RequestMethod.POST)
      public ModelAndView acceptFile(HttpServletRequest request, Model model, FormData formData,
          BindingResult result) {
    
        Object exception = request.getAttribute(DropOversizeFilesMultipartResolver.EXCEPTION_KEY);
        if (exception != null && FileUploadBase.SizeLimitExceededException.class.equals(exception.getClass())) {
          result.rejectValue("file", "<your.message.key>");
          LOGGER.error(exception);
        }
    

    the spring config remains the same. It would be really nice to have the exception transported to the validator, but I haven't figured out how to do this yet.