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来改变连接重置行为,但具体数值与实际的重置阈值似乎并非完全匹配,还需要进一步研究。

posted @ 2019-04-23 10:46  redreampt  阅读(250)  评论(0编辑  收藏  举报