SpringBoot When file upload size limit exceeds receiving MultipartException instead of MaxUploadSizeExceededException

I have a simple SpringBoot application file upload function, where the maximum file size for downloading files is 2 MB.

I configured multipart.max-file-size=2MB , it works fine. But when I try to upload files larger than 2 MB, I want to handle this error and show an error message.

To do this, my controller implements HandlerExceptionResolver with the implementation of resolveException() as follows:

 public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { Map<String, Object> model = new HashMap<String, Object>(); if (exception instanceof MaxUploadSizeExceededException) { model.put("msg", exception.getMessage()); } else { model.put("msg", "Unexpected error: " + exception.getMessage()); } return new ModelAndView("homepage", model); } 

The problem is that Exception Im get MultipartException instead of MaxUploadSizeExceededException .

Stacktrace element: Unable to parse a multi- hearted servlet request; The nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException: myFile field exceeds the maximum allowed size of 2097152 bytes.

If the file is oversized, why not get a MaxUploadSizeExceededException ? I get its parent MultipartException , which can occur for many other reasons in addition to file size.

Any thoughts on this?

+7
java spring-boot spring-mvc
source share
3 answers

I ran into the same problem, it seems that only the MultipartResolver of Commons File Upload implementation throws a MaxUploadSizeExceededException, but not the MultipartResolver Servlet 3.0 implementation.

Here is what I have done so far. The key here was to allow file verification on the controller, then you can check the size and fix the error.

  • set the multipart properties below the multipart: max-file-size: -1 max-request-size: -1

  • install Tomcat 8 (maxSwallowSize = "- 1")

  • on the controller, add logic to check the size

    if (fileAttachment.getSize ()> 10485760) {throw new MaxUploadSizeExceededException (fileAttachment.getSize ()); }

+2
source share

This is not great, but my quick and dirty solution was to check if the text MultipartException text String text SizeLimitExceededException and extract the maximum file size information from this message.

In my case, the exception that occurred on tomcat 8.0.x was org.apache.tomcat.util.http.fileupload.FileUploadBase $ SizeLimitExceededException: the request was rejected because its size (177351) exceeds the configured maximum (2048)

Keep in mind, as the almero noted, if you use CommonsMultipartResolver and not StandardServletMultipartResolver , then MaxUploadSizeExceededException will be MaxUploadSizeExceededException , which is much more convenient to handle. The following code handles a MultipartException generated using the multipart resolver strategy:

 @ControllerAdvice public class MultipartExceptionExceptionHandler { @ExceptionHandler(MultipartException.class) public String handleMultipartException(MultipartException ex, RedirectAttributes ra) { String maxFileSize = getMaxUploadFileSize(ex); if (maxFileSize != null) { ra.addFlashAttribute("errors", "Uploaded file is too large. File size cannot exceed " + maxFileSize + "."); } else { ra.addFlashAttribute("errors", ex.getMessage()); } return "redirect:/"; } private String getMaxUploadFileSize(MultipartException ex) { if (ex instanceof MaxUploadSizeExceededException) { return asReadableFileSize(((MaxUploadSizeExceededException)ex).getMaxUploadSize()); } String msg = ex.getMessage(); if (msg.contains("SizeLimitExceededException")) { String maxFileSize = msg.substring(msg.indexOf("maximum")).replaceAll("\\D+", ""); if (StringUtils.isNumeric(maxFileSize)) { return asReadableFileSize(Long.valueOf(maxFileSize)); } } return null; } // http://stackoverflow.com/a/5599842/225217 private static String asReadableFileSize(long size) { if(size <= 0) return "0"; final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" }; int digitGroups = (int) (Math.log10(size)/Math.log10(1024)); return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups]; } } 
0
source share

The following values โ€‹โ€‹in application.properties worked for me. It seems to make the permissible file size unlimited

 multipart.maxFileSize=-1 multipart.maxRequestSize=-1 

Now you need to add the logic from your controller.

 @PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { long size = file.getSize(); if(size > 10000000) { redirectAttributes.addFlashAttribute("message", "You file " + file.getOriginalFilename() + "! has not been successfully uploaded. Requires less than 10 MB size."); return "redirect:/upload"; } } 
-one
source share

All Articles