SpringBoot之设置上传文件大小

背景

关于zeus系统在F6已经落地有一段时间了

期间碰到过各种各样的问题和一些实践的经验。

比如如下碰到了SpringBoot的一些实践场景。

分析

SpringBoot帮助开发者做了许多隐蔽的事 在不了解的情况下其实最简单的办法就是搜索引擎

事实上大部分我们碰到的问题别人已经碰到了 比如之前觉得很不可以思议的问题sql巨慢之utf8mb4的隐藏问题

而且当一份代码摆在眼前 自己通过查看源码找到一些关键点就好比破案一般畅快!

检索

由于使用undertow可能报错有一些不太一样 我们有两条思路

首先找到关键词 UT000054 

我们可以通过搜索引擎检索SpringBoot的文件大小限制

SpringBoot做文件上传时出现了The field file exceeds its maximum permitted size of 1048576 bytes.错误,显示文件的大小超出了允许的范围。查看了官方文档,原来Spring Boot工程嵌入的tomcat限制了请求的文件大小,这一点在Spring Boot的官方文档中有说明,原文如下

65.5 Handling Multipart File Uploads
Spring Boot embraces the Servlet 3 javax.servlet.http.Part API to support uploading files. By default Spring Boot configures Spring MVC with a maximum file of 1Mb per file and a maximum of 10Mb of file data in a single request. You may override these values, as well as the location to which intermediate data is stored (e.g., to the /tmp directory) and the threshold past which data is flushed to disk by using the properties exposed in the MultipartProperties class. If you want to specify that files be unlimited, for example, set the multipart.maxFileSize property to -1.The multipart support is helpful when you want to receive multipart encoded file data as a @RequestParam-annotated parameter of type MultipartFile in a Spring MVC controller handler method.

文档说明表示,每个文件的配置最大为1Mb,单次请求的文件的总数不能大于10Mb。要更改这个默认值需要在配置文件(如application.properties)中加入两个配置

需要设置以下两个参数

multipart.maxFileSize
multipart.maxRequestSize

Spring Boot 1.3.x或者之前

multipart.maxFileSize=100Mb multipart.maxRequestSize=1000Mb

Spring Boot 1.4.x或者之后

spring.http.multipart.maxFileSize=100Mb spring.http.multipart.maxRequestSize=1000Mb

很多人设置了multipart.maxFileSize但是不起作用,是因为1.4版本以上的配置改了,详见官方文档:spring boot 1.4

http://blog.csdn.net/awmw74520/article/details/70230591

分析源码

假设我们无法判断代码的确切问题 搜索引擎上没有任何关键字

很容易可以从报错堆栈中找到如下

@Override
public void data(final ByteBuffer buffer) throws IOException {
    this.currentFileSize += buffer.remaining();
    if (this.maxIndividualFileSize > 0 && this.currentFileSize > this.maxIndividualFileSize) {
        throw UndertowMessages.MESSAGES.maxFileSizeExceeded(this.maxIndividualFileSize);
    }
    if (file == null) {
        while (buffer.hasRemaining()) {
            contentBytes.write(buffer.get());
        }
    } else {
        fileChannel.write(buffer);
    }
}
@Message(id = 54, value = "The maximum size %s for an individual file in a multipart request was exceeded")
IOException maxFileSizeExceeded(long maxIndividualFileSize);

原来是超过了最大上传size 那么OK我们来看这段逻辑 必然是这个maxIndividualFileSize=1M

只要比较愿意花时间看一下调用栈 很容易找到

public DispatcherServletRegistrationConfiguration(
      ServerProperties serverProperties, WebMvcProperties webMvcProperties,
      ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
   this.serverProperties = serverProperties;
   this.webMvcProperties = webMvcProperties;
   this.multipartConfig = multipartConfigProvider.getIfAvailable();
}

其实最终的

multipartConfig是从provider中获得的 而provider将会从bean容器中获取对应泛型的bean

那么简单找到是否有MultipartConfigElement的bean即可

@Bean
@ConditionalOnMissingBean
public MultipartConfigElement multipartConfigElement() {
   return this.multipartProperties.createMultipartConfig();
}

神奇的自动注入SpringBoot之自动配置

@ConfigurationProperties(prefix = "spring.http.multipart", ignoreUnknownFields = false)
public class MultipartProperties {
 
   /**
    * Enable support of multipart uploads.
    */
   private boolean enabled = true;
 
   /**
    * Intermediate location of uploaded files.
    */
   private String location;
 
   /**
    * Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or
    * kilobytes respectively.
    */
   private String maxFileSize = "1MB";
 
   /**
    * Max request size. Values can use the suffixes "MB" or "KB" to indicate megabytes or
    * kilobytes respectively.
    */
   private String maxRequestSize = "10MB";
 
   /**
    * Threshold after which files will be written to disk. Values can use the suffixes
    * "MB" or "KB" to indicate megabytes or kilobytes respectively.
    */
   private String fileSizeThreshold = "0";
 
   /**
    * Whether to resolve the multipart request lazily at the time of file or parameter
    * access.
    */
   private boolean resolveLazily = false;

很明显可以看到1M 10M的出现了

猜你喜欢

转载自blog.csdn.net/belalds/article/details/86248116