项目中需要控制上传文件的大小,采用了SpringBoot中的配置进行配置,并添加了相关的异常拦截处理。
- application.yaml
spring:
servlet:
multipart:
max-file-size: 5MB # 文件上传大小限制为5MB
max-request-size: 5MB # 请求大小限制为5MB
- 全局异常配置
@RestControllerAdvice
public class CustomExceptionHandler {
// 上传文件超过5M,捕获异常:MaxUploadSizeExceededException
@ExceptionHandler(MaxUploadSizeExceededException.class)
public ResutlCodeException handlerMaxUploadFile(MaxUploadSizeExceededException ex) {
return new ResutlCodeException("文件大小不能超过5MB");
}
}
在IEAD中启动项目,通过POSTMAN测试,可以正常拦截住超过限制的请求
将项目打包成war应用,部署在联调环境的Tomcat上,此时上传超过限制大小的文件,前端获取不到响应,处于无响应的情况,查看项目日志,发现没有任何相关日志。
推测此时请求被Tomcat中的相关配置拦截,未进入到Spring的校验中
修改tomcat下的配置tomcat_home/conf/server.xml
,在Connector节点下增加maxSwallowSize="-1"的配置
<Connector port="8080" protocol="HTTP/1.1" maxSwallowSize="-1" connectionTimeout ="200000" redirectPort ="8443"/>
<!-- maxSwallowSize="-1"表示tomcat不做限制 -->
<!-- tomcat版本为8.5 -->
此时服务端能正常响应请求,但是统一异常处理依旧无法处理异常
此时创建一个拦截器,判断文件大小,当不满足限制时抛出相同的异常,并将拦截器注入到Spring中,即可时项目正确捕获异常
- 拦截器
public class FileInterceptor implements HandlerInterceptor {
private long maxSize;
public FileInterceptor() {
// BeanFactory为继承了ApplicationContextAware的自定义类
MultipartProperties bean = BeanFactory.getBean(MultipartProperties.class);
DataSize maxFileSize = bean.getMaxFileSize();
this.maxSize = maxFileSize.toBytes();
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (request != null && ServletFileUpload.isMultipartContent(request)) {
ServletRequestContext context = new ServletRequestContext(request);
// 获取文件大小
long requestSize = context.contentLength();
if (requestSize > maxSize) {
throw new MaxUploadSizeExceededException(maxSize);
}
}
return true;
}
}
- 注册拦截器,并将顺序放至最前
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FileInterceptor())
.addPathPatterns("/fileUpload").order(Integer.MIN_VALUE);
}
}