SpringBoot 的 @MultipartConfig maxFileSize 没有生效

Posted

技术标签:

【中文标题】SpringBoot 的 @MultipartConfig maxFileSize 没有生效【英文标题】:SpringBoot's @MultipartConfig maxFileSize not taking effect 【发布时间】:2016-08-25 00:52:46 【问题描述】:

我有一个带有 MultipartConfig 注释的控制器(下面显示了一个 sn-p):

@RestController
@RequestMapping("packages")
@MultipartConfig(maxFileSize = 1024*1024*1024, maxRequestSize = 1024*1024*1024)
public class PackagesController

    @RequestMapping(method = RequestMethod.POST)
    public String create(@RequestParam("package") MultipartFile uploadedPackage)
    
        // do stuff to the file
        return "create";
    

不过,当我将文件上传到此端点时,它似乎正在使用默认的多部分配置值:

Caused by: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field package exceeds its maximum permitted size of 1048576 bytes.
    at org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl$FileItemStreamImpl$1.raiseError(FileUploadBase.java:633) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.checkLimit(LimitedInputStream.java:76) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:135) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at java.io.FilterInputStream.read(FilterInputStream.java:107) ~[na:1.8.0_45]
    at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:98) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:68) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:293) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    at org.apache.catalina.connector.Request.parseParts(Request.java:2776) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
    ... 30 common frames omitted

我的应用程序如下所示:

@SpringBootApplication
public class Application 

    public static void main(String[] args) 
        ApplicationContext ctx = SpringApplication.run(Application.class, args);
    


我是否缺少使@MultipartConfig 注释生效的东西?

【问题讨论】:

我能够通过使用带有 Bean 注释的 MultipartConfigFactory 方法的单独 AppConfig 类来使其工作,但我仍然不确定为什么它不能与上面的 MultipartConfig 注释一起使用。 @MultipartConfig 是一个 Servlet 注释。 Spring MVC 对此一无所知。 请参阅here,了解如何在标准 Spring MVC 中启用多部分处理。有了 Boot,情况就有些不同了。 重启tomcat(或其他容器)也可以。 【参考方案1】:

如果只想控制多部分属性,可以使用multipart.max-file-sizemultipart.max-request-size 属性。例如,您可以通过在 application.properties 文件中添加以下配置来将最大大小提高到 100Mb

multipart.max-file-size=100MB
multipart.max-request-size=100MB

值可以使用后缀MBKB来表示兆字节千字节大小。

在底层,Spring Boot 将基于MultipartProperties 创建一个MultipartConfigElement,并且MultipartConfigElement 将用于Servlet 注册,如Spring MVC documentation 中所述。您可以查看 MultipartAutoConfigurationDispatcherServletConfiguration 和 Checkout Spring Boot documentation 了解更多信息。

【讨论】:

需要注意的是,这个是在Spring Boot的版本低于1.4的时候使用的。如果它是 1.4 或更高版本,则将使用另一组属性(在@Teebo 的答案中)。【参考方案2】:

使用 spring-boot 1.5.3 您应该在 application.yml 中使用以下代码

spring:
 http:
  multipart:
   max-file-size: 100MB
   max-request-size: 100MB

确保在 yaml 文件中使用空格而不是制表符。

【讨论】:

【参考方案3】:

要为分段上传设置自定义限制,将使用以下属性(样本大小为 30MB):

spring.http.multipart.max-file-size=30MB
spring.http.multipart.max-request-size=30MB

在我们公司的项目中,我发现其中一个是Spring Boot 1.3.5版本,所以

multipart.max-file-size=30MB
multipart.max-request-size=30MB

来自docs(v1.4.0):

Spring Boot 包含 Servlet 3 javax.servlet.http.Part API 支持上传文件。默认情况下 Spring Boot 配置 Spring MVC 每个文件最大文件为 1MB,文件数据最大为 10MB 在一个请求中。您可以覆盖这些值,以及 存储中间数据的位置(例如,/tmp 目录)以及数据刷新到磁盘的阈值 使用MultipartProperties 类中公开的属性。如果你 想要指定文件不受限制,例如,设置 spring.http.multipart.max-file-size 属性为-1

当您想要接收多部分时,多部分支持很有帮助 将文件数据编码为 @RequestParam-annotated 类型的参数 MultipartFile 在 Spring MVC 控制器处理程序方法中。

1.3.8 版的相同文档:

如果您想指定文件不受限制,例如,设置 multipart.maxFileSize 属性为-1

【讨论】:

【参考方案4】:

使用 Spring Boot 2.0,您应该在 application.yml 中使用它

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

来自documentation:

Spring Boot 采用 Servlet 3 javax.servlet.http.Part API 来支持上传文件。默认情况下,Spring Boot 将 Spring MVC 配置为每个文件的最大大小为 1MB,单个请求中的文件数据最大为 10MB。您可以使用MultipartProperties 类中公开的属性覆盖这些值、中间数据的存储位置(例如,/tmp 目录)以及数据刷新到磁盘的阈值。例如,如果您想指定文件不受限制,请将 spring.servlet.multipart.max-file-size 属性设置为 -1

摘自Appendix A of documentation

spring.servlet.multipart.max-file-size=1MB # 最大文件大小。值可以使用后缀“MB”或“KB”分别表示兆字节或千字节。

spring.servlet.multipart.max-request-size=10MB # 最大请求大小。值可以使用后缀“MB”或“KB”分别表示兆字节或千字节。

【讨论】:

【参考方案5】:

对于 Spring Boot v2+,将以下内容添加到 application.properties:

spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=40MB

【讨论】:

取决于spring boot版本,看其他答案 用于 spring-boot 版本 2+【参考方案6】:

在部署时,通过 jenkins 脚本插入值,不允许使用“-”。使用:

env:
  - name: SPRING_SERVLET_MULTIPART_MAXREQUESTSIZE
    value: "10MB"
  - name: SPRING_SERVLE
    value: "10MB"

【讨论】:

【参考方案7】:

应用程序属性是一种选择。另一种选择是

@Bean
public MultipartConfigElement multipartConfigElement() 
  MultipartConfigFactory factory = new MultipartConfigFactory();
  factory.setMaxFileSize("10MB");
  factory.setMaxRequestSize("10MB");
  return factory.createMultipartConfig();

【讨论】:

以上是关于SpringBoot 的 @MultipartConfig maxFileSize 没有生效的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot入门到精通-SpringBoot自定义starter

SpringBoot.06.SpringBoot日志管理

SpringBoot.06.SpringBoot日志管理

Springboot 启动加载机制

springboot的工作原理

如何把springboot插件删除干净