Spring Boot句柄SizeLimitExceededException

时间:2017-10-12 11:40:17

标签: java spring-boot

我使用Spring boot 1.5.7 我没有配置CommonsMultipartResolver,因为Spring Boot已经处理了文件上传。

如果我的上传超过了最大允许的大小,则会抛出一个丑陋的异常 这是由我的控制器处理的。

@ControllerAdvice
public abstract class DefaultController implements InitializingBean {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ServiceException> handleException(final Exception ex) {
        ...
        } else if (ex instanceof MultipartException) {
            MultipartException me = (MultipartException) ex;
            Throwable cause = ex.getCause();
            if (cause instanceof IllegalStateException) {
                Throwable cause2 = cause.getCause();
                if (cause2 instanceof SizeLimitExceededException) {
                    // this is tomcat specific
                    SizeLimitExceededException slee = (SizeLimitExceededException) cause2;
                }
            }
        }

这种处理不仅复杂,而且特别是Tomcat,因为SizeLimitExceededException在包org.apache.tomcat.util.http.fileupload.FileUploadBase中。

我如何处理错误情况,有人会上传一个更大的文件然后允许并返回一条好消息,无论使用哪个Servlet引擎?

1 个答案:

答案 0 :(得分:3)

您可以在@ControllerAdvice中定义一个专门针对MultipartException的异常处理方法,然后使用特定的HttpStatus对其进行限定。例如:

@ExceptionHandler(MultipartException.class)
@ResponseStatus(value = HttpStatus.PAYLOAD_TOO_LARGE)
public ResponseEntity<ServiceException> handleMultipartException(MultipartException ex) {
    ...
}

这应该允许您专注于“最大文件大小”异常,而无需进入servlet容器细节。

更新1 以回应此评论:

  

听起来不错,SizeLimitExceededException提供的getPermittedSize和getActualSize是否有机会不仅在使用Tomcat时获取此值?

通过在(a)异常类型和(b)HTTP状态的基础上拦截此错误...您正在使解决方案普遍适用。但是这样做可能会丢失一个servlet容器(但可能不是另一个)可能给你的详细信息。您可以设置spring.http.multipart.max-file-size来强制执行自己的最大尺寸,在这种情况下,您可以报告“允许的尺寸”,但如果您要报告“实际尺寸”,则必须考虑以下其中一项:

  • 必须使用servlet容器提供的东西
  • 选择一个spring.http.multipart.max-file-size,它小于servlet容器支持的最大值,然后在控制器中应用自己的最大大小检查,并抛出包含实际和允许大小的特定异常类型。