做了一个上传文件的功能,前端通过文件流程的形式调用后台接口。几百k的文件能成功,几M的文件会失败。原因有二
第一是被nginx限制,请求也无法转发到应用服务器里面(也就是tomcat看不到请求日志只有nginx日志能看到请求)。如果nginx没有配置则默认是1M, 超过就会报错413 Request EntityToo Large。
解决方法:去nginx的conf目录下,编辑nginx.conf文件里面的http{},在里面添加一行配置如下
http{
client_max_body_size 100m; # 添加这一行,限制文件上传大小为100M
}
如果已设置了,看下是不是值设置的太小了,按需改大即可。最后要重启一下nginx使得生效。(建议放http里面,全局有效,免得哪天又又幺蛾子出现了)
设置到http{}内,控制全局nginx所有请求报文大小
设置到server{}内,控制该server的所有请求报文大小
设置到location{}内,控制满足该路由规则的请求报文大小
第二是 项目框架限制。比如springboot的MultipartFile,它也默认限制了上传的文件大小是1M左右。解决方法跟nginx类似。先看后台上传接口
@ResponseBody
@RequestMapping("/upload")
public String getToken(@RequestPart("multfile") MultipartFile multfile){
// 业务代码 略
}
先看注解 @RequestPart 和 @RequestParam 都是可以的,问题不在这,在看 @RequestPart(“multfile”) 里面的multfile,postman的入参字段名称不填写或者填写的与后台接口的入参字段名称不一致也不会成功 会报错 Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'multfile' is not present]
也就是接收不到你的入参文件流
上面ok后,上传一个大一点的文件报错信息如下, 1048576 bytes 大约是1M,也就是提示你上传最大限制1M文件。
Forwarding to error page from request [/file/upload] due to exception [Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field multfile exceeds its maximum permitted size of 1048576 bytes.]
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field multfile exceeds its maximum permitted size of 1048576 bytes.
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.handleParseFailure
解决方法: 在项目的application.yaml(或者application.properties文件)里面新增配置如下
# application.yaml 的写法
spring:
servlet:
multipart:
max-file-size: 50MB # 限制上传文件大小为50M, 如果不限制设为 -1
max-request-size: 50MB # 限制上传文件大小为50M, 如果不限制设为 -1
# application.properties 的写法
spring.servlet.multipart.maxFileSize=50M
spring.servlet.multipart.maxRequestSize=50M
# 根据自己的配置文件类型任选其一,注意格式问题以免读取不到
如果添加了还是不行仍报错 1048576 bytes 这个提示。注意检查下项目使用的springboot版本,可以去pom文件里面看或者写个main方法
public class Test {
public static void main(String[] args) {
String versionSpring = SpringVersion.getVersion();
String versionSpringBoot = SpringBootVersion.getVersion();
System.out.println("Spring Version:" + versionSpring);
System.out.println("SpringBoot Version:" + versionSpringBoot);
}
}
不同的springboot版本,其配置项略有不同,以为application.properties 的写法为例
# SpringBoot 1.3.x 以下
multipart.maxFileSize=50M
multipart.maxRequestSize=50M
# SpringBoot 1.4.x 至 1.5.x
spring.http.multipart.maxFileSize=50M
spring.http.multipart.maxRequestSize=50M
# SpringBoot 2.x 以上
spring.servlet.multipart.maxFileSize=50M
spring.servlet.multipart.maxRequestSize=50M
最后若这种添加配置的方法还是不行,尝试千万遍还是没读取到或者不起效果。那就放弃添加配置的方法,改为自己写个MultipartFile配置类(复制到自己的项目下即可,重启测试上传功能就ok了)
package com.yulisao.demo;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;
import javax.servlet.MultipartConfigElement;
/**
* author yulisao
* createDate 2023/01/07
*/
@Configuration
public class MultipartFileConfig {
// 都默认100M文件大小限制。 建议不写死,放配置
private final static Long maxFileSize = 100L;
private final static Long maxRequestSize = 100L;
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 注意这个set方法的单位是字节, 限制100M所以是 100*1024*1024
//factory.setMaxFileSize(maxFileSize*1024*1024); // SpringBoot低版本写法
//factory.setMaxRequestSize(maxRequestSize*1024*1024);
factory.setMaxFileSize(DataSize.ofMegabytes(maxFileSize*1024*1024)); // SpringBoot高版本写法
factory.setMaxRequestSize(DataSize.ofMegabytes(maxRequestSize*1024*1024));
return factory.createMultipartConfig();
}
}