I use Spring boot 1.5.7.
I have not configured CommonsMultipartResolver, because Spring Boot handles file uploads already.
If my upload exceeds the maximum permited size, an ugly Exception is thrown.
This is handled by my controller.
@ControllerAdvice
public abstract class DefaultController implements InitializingBean {
@ExceptionHandler(Exception.class)
public ResponseEntity<ServiceException> handleException(final Exception ex) {
...
} else if (ex instanceof MultipartException) {
MultipartException me = (MultipartException) ex;
Throwable cause = ex.getCause();
if (cause instanceof IllegalStateException) {
Throwable cause2 = cause.getCause();
if (cause2 instanceof SizeLimitExceededException) {
// this is tomcat specific
SizeLimitExceededException slee = (SizeLimitExceededException) cause2;
}
}
}
This kind of handling is not only complex but also sadly Tomcat specific, because the SizeLimitExceededException is in the package org.apache.tomcat.util.http.fileupload.FileUploadBase
.
How can I handle the error case, that some one uploads a bigger file then allowed and return a nice message, regardless which Servlet Engine is used?
You could define a exception handler method in your @ControllerAdvice
which is specifically for MultipartException
and then qualify it with a specific HttpStatus
. For example:
@ExceptionHandler(MultipartException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
public ResponseEntity<ServiceException> handleMultipartException(MultipartException ex) {
...
}
This should allow you to focus on the 'maximum file size' exception without having to get into servlet container specifics.
Update 1 in response to this comment:
Sounds good, what about getPermittedSize and getActualSize provided by SizeLimitExceededException is there a chance to get this values not only if Tomcat is used?
By intercepting this error on the basis of (a) the exception type and (b) the HTTP status ... you are making the solution generally applicable. But in so doing you might lose the sort of detailed information that one servlet container (but perhaps not another) might give you. You could perhaps enforce your own maximum size by setting spring.http.multipart.max-file-size
in which case you would be able to report 'permitted size' but if you want to report 'actual size' then you'll have to consider one of the following:
spring.http.multipart.max-file-size
which is less thatn the supported maximum for your servlet container and then apply your own max size check inside your controller and throw your own specific exception type containing the actual and permitted sizes.This working fine in my @RestControllerAdvice and the exception is more specific than MultipartException :
@ExceptionHandler(MaxUploadSizeExceededException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
public ResponseEntity handleMultipartException(MaxUploadSizeExceededException e) {
Map<String, String> result = new HashMap<>();
result.put("message", "Error ==> Large File ");
return ResponseEntity.status(HttpStatus.PAYLOAD_TOO_LARGE)
.body(result);
}
PS : when using @RestControllerAdvice(annotations = RestController.class) it doens't work .. you have to put @RestControllerAdvice without RestController.class annotation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With