问题
I have controller like this:
@PostMapping("/rest_upload1")
public ResponseEntity upload1(@RequestParam("file") MultipartFile multipartFile) throws IOException {
throw new IllegalArgumentException();
}
and in configuration I have settings:
spring.http.multipart.max-file-size=100MB
spring.http.multipart.max-request-size=100MB
it means that spring will throw MultipartException
in case if file exceeds 100MB.
To handle this exception I wrote handler:
@ControllerAdvice
public class RestExceptionHandlerAdvice extends ResponseEntityExceptionHandler {
@ExceptionHandler(MultipartException.class)
@ResponseBody
public ResponseEntity<ApiError> handleException(MultipartException e) {
logger.warn("MultipartException:", e);
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST,
String.valueOf(HttpStatus.BAD_REQUEST),
ExceptionUtils.getRootCauseMessage(e),
Collections.emptyList());
return new ResponseEntity<ApiError>(apiError, HttpStatus.BAD_REQUEST);
}
In case of error this code invokes(i see it in debug)
but in browser I don't see response:
I googled a lot of time and looked loke everuthing ok. And I tried to add handler for IllegalArgumentException:
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public ResponseEntity<ApiError> handleException(IllegalArgumentException e) {
ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST,
String.valueOf(HttpStatus.BAD_REQUEST),
ExceptionUtils.getRootCauseMessage(e),
Collections.emptyList());
return new ResponseEntity<ApiError>(apiError, HttpStatus.BAD_REQUEST);
}
And I upload file less than 100mb. At this case result differs:
But anyway response code is wrong.
What can be wrong?
P.S.
I tried:
@ExceptionHandler(MultipartException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
@ResponseBody
public String handleException(MultipartException e) {
return ExceptionUtils.getRootCauseMessage(e);
}
it looks like the same as here:
How to handle maximum file size Exception in Spring Boot?
P.S.2
I found workaround but it looks like bug in sring:
I added dependencies:
compile "org.apache.commons:commons-io:1.3.2"
compile "commons-fileupload:commons-fileupload:1.3.3"
register beans:
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(10);
return multipartResolver;
}
and wrote:
@ControllerAdvice
public class UploadExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
@ResponseStatus(HttpStatus.PAYLOAD_TOO_LARGE)
@ResponseBody
public String handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
return e.getMessage();
}
}
回答1:
Not very clever tomcat developers added new feature which we need to disable/override.
It is working after I have added:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
// connector other settings...
// configure maxSwallowSize
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
// -1 means unlimited, accept bytes
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return tomcat;
}
来源:https://stackoverflow.com/questions/47396772/tomcat-exceptionhasndler-doesnt-work-for-multipartexception-but-works-correct