- 新建一个统一异常处理的一个类
- 类上标注 @RestControllerAdvice 这一个注解,或者同时标注 @ControllerAdvice 和 @ResponseBody
这两个注解。 - 在方法上标注 @ExceptionHandler 注解,并且指定需要捕获的异常,可以同时捕获多个
/**
* 全局统一的异常处理,简单的配置下,根据自己的业务要求详细配置
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 重复请求的异常
* @param ex
* @return
*/
@ExceptionHandler(RepeatSubmitException.class)
public ResultResponse onException(RepeatSubmitException ex){
//打印日志
log.error(ex.getMessage());
//todo 日志入库等等操作
//统一结果返回
return new ResultResponse(ResultCodeEnum.CODE_NOT_REPEAT_SUBMIT);
}
/**
* 自定义的业务上的异常
*/
@ExceptionHandler(ServiceException.class)
public ResultResponse onException(ServiceException ex){
//打印日志
log.error(ex.getMessage());
//todo 日志入库等等操作
//统一结果返回
return new ResultResponse(ResultCodeEnum.CODE_SERVICE_FAIL);
}
/**
* 捕获一些进入controller之前的异常,有些4xx的状态码统一设置为200
注意:上面的只是一个例子,实际开发中还有许多的异常需要捕获,比如 TOKEN失效 、 过期 等等异常,
如果整合了其他的框架,还要注意这些框架抛出的异常,比如 Shiro , Spring Security 等等框架。
异常匹配的顺序是什么?
* @param ex
* @return
*/
@ExceptionHandler({HttpRequestMethodNotSupportedException.class,
HttpMediaTypeNotSupportedException.class, HttpMediaTypeNotAcceptableException.class,
MissingPathVariableException.class, MissingServletRequestParameterException.class,
ServletRequestBindingException.class, ConversionNotSupportedException.class,
TypeMismatchException.class, HttpMessageNotReadableException.class,
HttpMessageNotWritableException.class,
MissingServletRequestPartException.class, BindException.class,
NoHandlerFoundException.class, AsyncRequestTimeoutException.class})
public ResultResponse onException(Exception ex){
//打印日志
log.error(ex.getMessage());
//todo 日志入库等等操作
//统一结果返回
return new ResultResponse(ResultCodeEnum.CODE_FAIL);
}
}
//处理器捕获,精确匹配,如果没有 ServiceException 的异常处理器才会轮到它的 父亲 , 父亲 没有才会到 祖父 。总之一句话,精准匹配,找那个关系最近的。