1. 概述

在Spring框架中,当应用程序尝试上传文件大小超过配置中指定阈值时,会抛出MaxUploadSizeExceededException异常。

本文将介绍如何设置最大上传大小,然后展示一个简单的文件上传控制器,并讨论处理这种异常的不同方法。

2. 设置最大上传大小

默认情况下,没有对可上传文件大小的限制。要设置最大上传大小,你需要声明一个MultipartResolver类型的bean。

以下示例将文件大小限制为5 MB:

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver
      = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(5242880);
    return multipartResolver;
}

3. 文件上传控制器

接下来,我们定义一个处理文件上传和保存到服务器的方法:

@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public ModelAndView uploadFile(MultipartFile file) throws IOException {
 
    ModelAndView modelAndView = new ModelAndView("file");
    InputStream in = file.getInputStream();
    File currDir = new File(".");
    String path = currDir.getAbsolutePath();
    FileOutputStream f = new FileOutputStream(
      path.substring(0, path.length()-1)+ file.getOriginalFilename());
    int ch = 0;
    while ((ch = in.read()) != -1) {
        f.write(ch);
    }
    
    f.flush();
    f.close();
    
    modelAndView.getModel().put("message", "File uploaded successfully!");
    return modelAndView;
}

如果用户尝试上传大于5 MB的文件,应用程序将抛出MaxUploadSizeExceededException类型的异常。

4. 处理MaxUploadSizeExceededException

为了处理这个异常,我们的控制器可以实现HandlerExceptionResolver接口,或者创建一个带有@ControllerAdvice注解的类。

4.1. 实现HandlerExceptionResolver

HandlerExceptionResolver接口声明了一个名为resolveException()的方法,用于处理不同类型的异常。

让我们重写resolveException()方法,在捕获到MaxUploadSizeExceededException类型异常时显示一条消息:

@Override
public ModelAndView resolveException(
  HttpServletRequest request,
  HttpServletResponse response, 
  Object object,
  Exception exc) {   
     
    ModelAndView modelAndView = new ModelAndView("file");
    if (exc instanceof MaxUploadSizeExceededException) {
        modelAndView.getModel().put("message", "File size exceeds limit!");
    }
    return modelAndView;
}

4.2. 创建控制器建议拦截器

通过拦截器处理异常比直接在控制器中处理有多个优点。例如,我们可以将相同的异常处理逻辑应用到多个控制器上。

另一个优点是,我们可以创建一个只针对我们想要处理的特定异常的方法,这样框架就可以将异常处理委派给我们,而无需使用instanceof检查抛出的是哪种类型的异常:

@ControllerAdvice
public class FileUploadExceptionAdvice {
     
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ModelAndView handleMaxSizeException(
      MaxUploadSizeExceededException exc, 
      HttpServletRequest request,
      HttpServletResponse response) {
 
        ModelAndView modelAndView = new ModelAndView("file");
        modelAndView.getModel().put("message", "File too large!");
        return modelAndView;
    }
}

5. Tomcat配置

如果你部署到Tomcat 7及以上版本的服务器,可能需要设置或修改一个名为maxSwallowSize的配置属性。

这个属性指定了当服务器知道将忽略文件时,Tomcat将为客户端上传吞咽的最大字节数。

该属性的默认值是2097152(2 MB)。如果不更改或设置低于我们在MultipartResolver中设置的5 MB限制,Tomcat将拒绝任何超过2 MB的文件上传,我们的自定义异常处理将不会被调用。

为了让请求成功并显示应用程序的错误消息,你需要将maxSwallowSize属性设置为负值。这指示Tomcat无论文件大小如何,都要吞咽所有失败的上传。

这在TOMCAT_HOME/conf/server.xml文件中完成:

<Connector port="8080" protocol="HTTP/1.1"
  connectionTimeout="20000"
  redirectPort="8443" 
  maxSwallowSize = "-1"/>

6. 总结

本文展示了如何在Spring中配置最大文件上传大小,以及当客户端尝试上传超过此限制的文件时如何处理MaxUploadSizeExceededException异常。

本文的完整源代码可以在GitHub项目中找到。