SpringBoot系列之设置上传文件大小的方式
Springboot设置上传文件大小的方式
配置Bean
当前类上需要加注解@Configuration
/**
* 文件上传配置
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 单个文件最大
factory.setMaxFileSize("10240KB");
// 多个文件总大小
factory.setMaxRequestSize("102400KB");
return factory.createMultipartConfig();
}
对应的配置工厂类MultipartConfigFactory
private long parseSize(String size) {
Assert.hasLength(size, "Size must not be empty");
size = size.toUpperCase();
if (size.endsWith("KB")) {
return Long.valueOf(size.substring(0, size.length() - 2)) * 1024L;
} else {
return size.endsWith("MB") ? Long.valueOf(size.substring(0, size.length() - 2)) * 1024L * 1024L : Long.valueOf(size);
}
application.properties
spring.http.multipart.maxFileSize=10Mb
spring.http.multipart.maxRequestSize=10Mb
Spring Boot 2.0+版本
spring.servlet.multipart.max-file-size=10Mb
spring.servlet.multipart.max-request-size=10Mb
Mb和Kb都可以。
对应的配置解析类MultipartProperties。
问题
两种方式同时存在时,优先级如何,哪个配置生效?写一个Controller测试一下:
@RequestMapping(value = "upload", method = RequestMethod.POST, produces = "application/json")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile[] files) {
return "";
}
application.yml
配置文件:
spring:
http:
multipart:
maxFileSize: 1MB
maxRequestSize: 1MB
location: D:\\doc
@Bean配置文件:
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("5MB");
factory.setMaxRequestSize("5MB");
factory.setLocation("D:\\");
return factory.createMultipartConfig();
}
第一次上传下面的2M+文件,未报错;第二次上传9M+文件
报错:
WARN org.eclipse.jetty.server.HttpChannel- /upload
java.lang.IllegalStateException: Request exceeds maxRequestSize (5242880)
这是否说明@Bean优先级更高?还是以最大值来生效?严谨一点,把两个地方的配置换一下位置,结果报错:
org.eclipse.jetty.server.HttpChannel- /upload
java.lang.IllegalStateException: Request exceeds maxRequestSize (1048576)
结论:@Bean的配置优先级更高。
另一方面,可以通过在启动设设置断点(MultipartConfigFactory以及MultipartProperties)来调试验证,MultipartConfigFactory总是先被set数据:
原理
TODO
其他
注意到上面的Controller接口定义里面,是一个MultipartFile数组,即支持一次上传多个文件,页面调试当然没有问题,前端JS设置一下即可。但是postman当前最新版v8.11.1不支持添加多个文件。
拓展
报错拦截
@MultipartConfig
javax.servlet-api里面的一个注解,源码如下:
package javax.servlet.annotation;
/**
* Annotation that may be specified on a {@link javax.servlet.Servlet}
* class, indicating that instances of the <tt>Servlet</tt> expect requests
* that conform to the <tt>multipart/form-data</tt> MIME type.
*
* <p>Servlets annotated with <tt>MultipartConfig</tt> may retrieve the
* {@link javax.servlet.http.Part} components of a given
* <tt>multipart/form-data</tt> request by calling
* {@link javax.servlet.http.HttpServletRequest#getPart getPart} or
* {@link javax.servlet.http.HttpServletRequest#getParts getParts}.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MultipartConfig {
/**
* The directory location where files will be stored
*/
String location() default "";
/**
* The maximum size allowed for uploaded files.
*
* <p>The default is <tt>-1L</tt>, which means unlimited.
*/
long maxFileSize() default -1L;
/**
* The maximum size allowed for <tt>multipart/form-data</tt>
* requests
*
* <p>The default is <tt>-1L</tt>, which means unlimited.
*/
long maxRequestSize() default -1L;
/**
* The size threshold after which the file will be written to disk
*/
int fileSizeThreshold() default 0;
}