Spring MVC 文件上传功能
前言
在Spring MVC中实现文件上传功能并不复杂,前端使用HTML语法,后端使用特定抽象,参考Spring Boot相关文档即可。本文主要讲解常见资料忽略的两个问题:
- 文件上传错误
- 链接重置问题
版本:Spring Boot 1.5.x
文件上传错误
如何处理文件上传期间发生的错误是一个重要的关注点,错误主要分为两类:
- IOException 文件读取或写入错误。
- MultipartException 上传文件时,超过文件大小上限所触发的异常。
IOException
只需要在Controller层完成捕获和处理,处理方式可以是重定向并附带错误消息到提交页面。
MultipartException
如果文件大小超出设定允许的上限,将抛出该异常。MultipartException是Spring MVC的分派异常,其处理逻辑理应由HandlerExceptionResolver
处理,如果未处理则交给Servlet容器处理。
使用Spring MVC异常处理机制
可以使用@ExceptionHandler
功能来实现:
@ExceptionHandler(MultipartException.class)
public String handleUploadError(HttpServletRequest request){
return "forward:/uploadError";
}
使用ErrorPage机制
也可以使用Spring Boot底层的ErrorPage机制,默认情况Spring Boot注册了一个Global ErrorPage,它会处理所有未明确映射ErrorPage的异常和错误码。
你可以添加自定义ErrorPage:
@Bean("mulitpartExceptionErrorPageRegistrar")
public ErrorPageRegistrar mulitpartExceptionErrorPageRegistrar(){
return new ErrorPageRegistrar() {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(MultipartException.class,"/uploadError"));
}
};
}
连接重置问题
测试发现,当上传过大的文件时会出现连接重置问题。原因是因为根据HTTP协议,server只有接受完请求后才能返回响应,tomcat对终止上传后依然接受的请求数据大小存在限制,超过该限制将中断TCP连接。
实际测试表明,默认情况下(最大文件大小为2M),其连接重置阈值大约为3M左右。
Spring Boot配置参数spring.http.multipart.max-request-size表示当请求大小超出该限制时,服务器将该拒绝请求,其并不影响连接重置。
设置tomcat的maxSwallowSize来改变连接重置行为,但具体数值与实际的重置阈值似乎并非完全匹配,还需要进一步研究。