多部分文件最大大小异常 - spring 嵌入式启动 tomcat
Multipart file maximum size exception - spring boot embbeded tomcat
我已将最大文件大小设置为
multipart.maxFileSize: 1mb
multipart.maxRequestSize: 1mb
这是我的控制器:
@RequestMapping(method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.CREATED)
@Secured(Privileges.CAN_USER_READ)
public void create(@RequestParam("file")final MultipartFile file,Principal principal) throws IllegalStateException, IOException,MultipartException{
medicalHistoryService.create(new MedicalHistory(file));
}
这是错误信息
2016-03-03 13:48:24.560 WARN 4992 --- [nio-8080-exec-1] h.c.w.RestResponseEntityExceptionHandler : Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (9288401) exceeds the configured maximum (1048576)
2016-03-03 13:48:25.545 WARN 4992 --- [nio-8080-exec-2] h.c.w.RestResponseEntityExceptionHandler : Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (9288401) exceeds the configured maximum (1048576)
请求文件过大后的最终结果是加载页面时出现问题。我在堆栈跟踪中没有收到任何其他错误,所以我有点被实际发生的事情困住了。哦,是的,我尝试了许多其他解决方案,例如注册过滤器、在 ErrorController 中处理异常。每次我都会得到相同的结果 - 服务器崩溃。
编辑 2
我的异常处理class:
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
// 413 MultipartException - file size too big
@ExceptionHandler({MultipartException.class,FileSizeLimitExceededException.class,java.lang.IllegalStateException.class})
public ResponseEntity<Object> handleSizeExceededException(final WebRequest request, final MultipartException ex) {
//log.warn("413 Status Code. File size too large {}", ex.getMessage());
log.warn(ex.getMessage());
final ApiError apiError = message(HttpStatus.PAYLOAD_TOO_LARGE, ex);
return handleExceptionInternal(ex, apiError, new HttpHeaders(), HttpStatus.PAYLOAD_TOO_LARGE, request);
}
}
这很棘手。 Tomcat 属性 MaxSwallowSize 导致了这个问题。显然它是在 Tomcat 的最新版本之一中引入的。它背后的整个想法是,如果 Tomcat 意识到请求将被拒绝,则终止任何高于默认 2mb 的连接(至少这是我的解释)。简单地覆盖此 属性 即可解决问题。我意识到这不是完美的解决方案,但它比仅仅终止连接要好得多。
@Bean
public TomcatEmbeddedServletContainerFactory containerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return factory;
}
从 Spring 引导 2 开始
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
见docs
Spring开机1.x
属性应该是这样的:
spring.http.multipart.max-file-size=128KB
spring.http.multipart.max-request-size=128KB
我在 application.yml 中写了一些行来解决这个问题,例如:
spring:
http:
multipart:
max-file-size: 10MB
max-request-size: 10MB
但是并没有解决问题。但是,在格式化为单行方式后在 application.properties 中添加相同的行,即属性文件方式然后它起作用了。
请在 application.properties 中为 spring 引导版本添加以下行 -2.0.1.RELEASE
spring.servlet.multipart.max-file-size=128MB
spring.servlet.multipart.max-request-size=128MB
spring.servlet.multipart.enabled=true
这解决了我的问题。
因为@SeaBiscuit 提供了正确的答案,但是 Spring 启动 2.0.0.RELEASE
class org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
已被删除并替换为 class org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
。
所以新 Spring 引导 2.0.0 的代码将是
- 创建一个任意名称的class并用
@Configuration
注释
- 然后将下面的代码放入 class
@Bean
public TomcatServletWebServerFactory containerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return factory;
}
如果您在 Spring 引导 2.0.0 中配置最大文件上传大小有问题
将下面的代码放入 'application.propertise' 文件中,所需文件大小为“MB”
## Image upload limitation properties
spring.servlet.multipart.max-file-size=3MB
spring.servlet.multipart.max-request-size=3MB
下面的代码对我有用。将其添加到 spring boot main class:
import javax.servlet.MultipartConfigElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("5MB");
factory.setMaxRequestSize("5MB");
return factory.createMultipartConfig();
}
}
我尝试了上面的所有建议,但在添加以下内容之前仍然出现错误:
server.tomcat.max-swallow-size=-1
在 application.properties 文件中。
我已将最大文件大小设置为
multipart.maxFileSize: 1mb
multipart.maxRequestSize: 1mb
这是我的控制器:
@RequestMapping(method=RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.CREATED)
@Secured(Privileges.CAN_USER_READ)
public void create(@RequestParam("file")final MultipartFile file,Principal principal) throws IllegalStateException, IOException,MultipartException{
medicalHistoryService.create(new MedicalHistory(file));
}
这是错误信息
2016-03-03 13:48:24.560 WARN 4992 --- [nio-8080-exec-1] h.c.w.RestResponseEntityExceptionHandler : Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (9288401) exceeds the configured maximum (1048576)
2016-03-03 13:48:25.545 WARN 4992 --- [nio-8080-exec-2] h.c.w.RestResponseEntityExceptionHandler : Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (9288401) exceeds the configured maximum (1048576)
请求文件过大后的最终结果是加载页面时出现问题。我在堆栈跟踪中没有收到任何其他错误,所以我有点被实际发生的事情困住了。哦,是的,我尝试了许多其他解决方案,例如注册过滤器、在 ErrorController 中处理异常。每次我都会得到相同的结果 - 服务器崩溃。
编辑 2
我的异常处理class:
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
// 413 MultipartException - file size too big
@ExceptionHandler({MultipartException.class,FileSizeLimitExceededException.class,java.lang.IllegalStateException.class})
public ResponseEntity<Object> handleSizeExceededException(final WebRequest request, final MultipartException ex) {
//log.warn("413 Status Code. File size too large {}", ex.getMessage());
log.warn(ex.getMessage());
final ApiError apiError = message(HttpStatus.PAYLOAD_TOO_LARGE, ex);
return handleExceptionInternal(ex, apiError, new HttpHeaders(), HttpStatus.PAYLOAD_TOO_LARGE, request);
}
}
这很棘手。 Tomcat 属性 MaxSwallowSize 导致了这个问题。显然它是在 Tomcat 的最新版本之一中引入的。它背后的整个想法是,如果 Tomcat 意识到请求将被拒绝,则终止任何高于默认 2mb 的连接(至少这是我的解释)。简单地覆盖此 属性 即可解决问题。我意识到这不是完美的解决方案,但它比仅仅终止连接要好得多。
@Bean
public TomcatEmbeddedServletContainerFactory containerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return factory;
}
从 Spring 引导 2 开始
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
见docs
Spring开机1.x
属性应该是这样的:
spring.http.multipart.max-file-size=128KB
spring.http.multipart.max-request-size=128KB
我在 application.yml 中写了一些行来解决这个问题,例如:
spring:
http:
multipart:
max-file-size: 10MB
max-request-size: 10MB
但是并没有解决问题。但是,在格式化为单行方式后在 application.properties 中添加相同的行,即属性文件方式然后它起作用了。
请在 application.properties 中为 spring 引导版本添加以下行 -2.0.1.RELEASE
spring.servlet.multipart.max-file-size=128MB
spring.servlet.multipart.max-request-size=128MB
spring.servlet.multipart.enabled=true
这解决了我的问题。
因为@SeaBiscuit 提供了正确的答案,但是 Spring 启动 2.0.0.RELEASE
class org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
已被删除并替换为 class org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory
。
所以新 Spring 引导 2.0.0 的代码将是
- 创建一个任意名称的class并用
@Configuration
注释
- 然后将下面的代码放入 class
@Bean
public TomcatServletWebServerFactory containerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return factory;
}
如果您在 Spring 引导 2.0.0 中配置最大文件上传大小有问题 将下面的代码放入 'application.propertise' 文件中,所需文件大小为“MB”
## Image upload limitation properties
spring.servlet.multipart.max-file-size=3MB
spring.servlet.multipart.max-request-size=3MB
下面的代码对我有用。将其添加到 spring boot main class:
import javax.servlet.MultipartConfigElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("5MB");
factory.setMaxRequestSize("5MB");
return factory.createMultipartConfig();
}
}
我尝试了上面的所有建议,但在添加以下内容之前仍然出现错误:
server.tomcat.max-swallow-size=-1
在 application.properties 文件中。