上传文件超过最大限制时无法捕获异常
最近在做一个视频检测需求,考虑到阿里云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>