上传文件超过最大限制时无法捕获异常

最近在做一个视频检测需求,考虑到阿里云OSS空间和网络带宽限制,对于客户端提交的视频文件有大小限制,信息配置在文件application.yml

spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 100MB
      max-request-size: 100MB

然后使用postman上传一个文件加以测试,响应报错信息为:
在这里插入图片描述
控制台(日志文件中)记录报错为:

com.central.common.exception.DefaultExceptionAdvice 未知异常
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 10485760 bytes.

这个报错信息太不友好。

未知异常这几个字的报错信息源头是DefaultExceptionAdvice:

@ResponseBody
@Slf4j
public class DefaultExceptionAdvice {
    /**
     * IllegalArgumentException异常处理返回json
     * 返回状态码:400
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({IllegalArgumentException.class})
    public Result badRequestException(IllegalArgumentException e) {
        return defHandler("参数解析失败", e);
    }

    /**
     * AccessDeniedException异常处理返回json
     * 返回状态码:403
     */
    @ResponseStatus(HttpStatus.FORBIDDEN)
    @ExceptionHandler({AccessDeniedException.class})
    public Result badMethodExpressException(AccessDeniedException e) {
        return defHandler("没有权限请求当前方法", e);
    }

    /**
     * 返回状态码:405
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public Result handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return defHandler("不支持当前请求方法", e);
    }

    /**
     * 返回状态码:415
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler({HttpMediaTypeNotSupportedException.class})
    public Result handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        return defHandler("不支持当前媒体类型", e);
    }

    /**
     * SQLException sql异常处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({SQLException.class})
    public Result handleSQLException(SQLException e) {
        return defHandler("服务运行SQLException异常", e);
    }

    /**
     * BusinessException 业务异常处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BusinessException.class)
    public Result handleException(BusinessException e) {
        return defHandler(e.getMessage(), e);
    }

    /**
     * 所有异常统一处理
     * 返回状态码:500
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        return defHandler("未知异常", e);
    }

    private Result defHandler(String msg, Exception e) {
        log.error(msg, e);
        return Result.failed(msg);
    }
}

业务应用可以自定义ExceptionAdvice并继承DefaultExceptionAdvice

@ControllerAdvice
public class ExceptionAdvice extends DefaultExceptionAdvice {
    @ExceptionHandler(MultipartException.class)
    @ResponseBody
    public String exception(MultipartException e) {
        // return e.getLocalizedMessage();
        return "上传文件最大不可超过100M";
    }
}

此时报错信息效果:
在这里插入图片描述
实现预期效果!

插曲:
我们再来看看报错信息:

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 10485760 bytes.

一开始看到FileSizeLimitExceededException,ExceptionHandler捕获FileSizeLimitExceededException

@ExceptionHandler(FileSizeLimitExceededException.class)
@ResponseBody
public String exception(SizeLimitExceededException e) {
	return e.getLocalizedMessage();     
}

结果并不能捕获。FileSizeLimitExceededException是tomcat-embed-core依赖包里面定义的异常。

切换成MaxUploadSizeExceededException,捕获成功。

看一下其他异常捕获方法:

@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public List<ErrorMsg> exception(MethodArgumentNotValidException e) {
}

MethodArgumentNotValidException可以捕获异常。

一个没有得到理论支持的结果
在使用ControllerAdvice和ExceptionHandler捕获异常时,只能捕获org.springframework.web下面的异常,即在下面依赖里面有定义的异常:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>
posted @ 2021-07-02 19:05  johnny233  阅读(57)  评论(0编辑  收藏  举报  来源