在web项目中,经常会遇到上传文件的需求,有时需要单个上传,有时需要批量上传。默认情况下,支持文件的大小是1M。当默认配置不符合业务需求时,需要我们调整支持文件上传大小的限制。若上传文件大小超过支持的大小,后台会抛出异常。本文主要基于springboot讲解如何配置支持文件的大小,并且对于超过大小时异常如何处理。
上传文件的请求提交到服务器之后,首先请求会交由SpringMVC的DispatcherServlet进行处理,调用该方法的doService方法进行请求处理;当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 ultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller。
resolveMultipart方法处理逻辑包含了对文件大小限制的判断,如果超过大小会抛出异常。
代码中,FileUpload类中的sizeMax和fileSizeMax的值来自于MultipartConfigElement类中的属性。也即在springboot中通过配置MultipartConfigElement类,来配置文件的大小。
1.后台配置支持文件大小的方式
1.1配置文件配置
spring.servlet.multipart.maxFileSize=100MB
spring.servlet.multipart.max-request-size=1024MB
1.2Bean方式配置
@Configuration
public class UploadConfig {
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//单个文件最大
factory.setMaxFileSize("20480KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("1024000KB");
return factory.createMultipartConfig();
}
}
2.上传文件超过指定大小的异常处理
如果文件超过设定的大小,后台会抛出MultipartException异常,FileSizeLimitExceededException、SizeLimitExceededException均是改异常的子类。为了能给用户友好的提示,我们需要对该异常进行处理,提示出系统支持文件的大小。
下面使用SpringBoot中统一异常处理的思路进行处理。
2.1配置Tomcat的MaxSwallowSize
//配置tomcat,使的上传文件超过设置的值时,进行提醒。
@Bean
public ServletWebServerFactory tomcatEmbedded() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
((AbstractHttp11Protocol<?>)
connector.getProtocolHandler()).setMaxSwallowSize(-1);
}
});
return tomcat;
}
maxSwallowSize配置用于配置上载的字节数,默认为2M。如果您尝试上传的文件大小超出了大小限制,则Tomcat会将其裁剪为默认的2mb并重置连接。
将maxSwallowSize设置为-1表示无限制。
----------------------对maxSwallowSize参数还需要进一步理解----------------------------
2.2统一异常配置
@ControllerAdvice
public class BaseController{
private final static Logger LOGGER = LoggerFactory.getLogger(BaseController.class);
@Autowired
MultipartConfigElement fileSizeConfig ;
@ExceptionHandler(value = MultipartException.class)
@ResponseBody
public String fileUploadExceptionHandler(MultipartException exception, HttpServletResponse response) {
String msg="";
Throwable rootCase=exception.getRootCause();
if (rootCase instanceof FileSizeLimitExceededException) {//单个文件超过大小
msg="单文件大小不得超过"+fileSizeConfig.getMaxFileSize()/1024/1024+"M";
}else if(rootCase instanceof SizeLimitExceededException){//总文件超过大小
msg="总文件大小不得超过"+fileSizeConfig.getMaxRequestSize()/1024/1024+"M";
}else {
msg="上传失败[服务器异常]";
}
LOGGER.error(msg, exception);
return ResultStandardUtil.importingFailMessage(msg);
}
}
其中MultipartConfigElement类可以获取到配置支持文件的大小。可以返回前端;
FileSizeLimitExceededException代表单个文件超过支持的大小;
SizeLimitExceededException代表所有文件超过支持的大小;
ResultStandardUtil.importingFailMessage(msg); 是约定返回格式的封装。
这样,当上传的文件超过指定的大小时,就能够将异常信息友好的返回给前端页面进行提示!
注意:该方式在Springboot2.0.5版本下测试可用,2.3版本不可用