18

I'm developing a endpoint with Spring Boot 2.1.3 (using the standard Tomcat embedded web server) to upload an image and I want to limit the size of the multipart upload. I can do this easily with the properties:

spring:
    servlet:
        multipart:
            max-file-size: 2MB
            max-request-size: 2MB

But I always get a 500 that Spring can't catch because is Tomcat that is throwing the exception and the request don't reach my code in the RestController.

2019-03-02 10:12:50.544 ERROR [] [   o.a.c.c.C.[.[.[/].[dispatcherServlet]] [] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3917946) exceeds the configured maximum (2097152)] with root cause 
org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (3917946) exceeds the configured maximum (2097152)

My ExceptionHandler is like this but obviously don't work whatever the exception that put in the annotation:

@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResponseEntity handleMaxSizeException(Exception e) {
    logger.warn(e.getMessage());
    ...
    return status(HttpStatus.PAYLOAD_TOO_LARGE).body(...);
}

I already tried this with the already mentioned properties but without any effect:

@Bean
public TomcatServletWebServerFactory containerFactory() {
    TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
    factory.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> 
        ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1));
    return factory;
}

I already checked the answers in the following questions (and others...) but they are mostly outdated or simply don't work:

Is somebody struggling with this?

voliveira89
  • 1,134
  • 2
  • 9
  • 22
  • I run into this after following suggestions : [ERR] Resource exhaustion event: the JVM was unable to allocate memory from the heap. – Smart Coder May 17 '22 at 17:27

3 Answers3

12

Please add this in your application.properties:

spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB

You can change the size as you need in the above config

CreativeJoe
  • 63
  • 1
  • 5
Nav K
  • 147
  • 1
  • 3
5

A bit late. You need set in application.properties or application.yml server.tomcat.max-swallow-size=-1 With it tomcat will not interferred in the upload request and the operation will be handle fully by spring and your exception controller will work perfectly. References

peterzinho16
  • 919
  • 1
  • 15
  • 18
0

Was having a similar problem. Tomcat kept complaining that the request was exceeding the configured maximum (2097152), even though I had the default settings in place in the global web.xml:

      <max-file-size>52428800</max-file-size>
      <max-request-size>52428800</max-request-size>

Finally figured out: the servlet class I am developing extends a servlet class that has the @MultipartConfig annotation, but my local class did not have the @MultipartConfig annotation. So the request was not being treated as multi-part, which was tripping this error.

The code that was throwing the error is in the super class at these lines:

//Search through the parts for an uploaded file
for (Part part : request.getParts()) {
jomofrodo
  • 1,119
  • 11
  • 19