全局异常处理
@ControllerAdvice注解:
- 不写参数:所有Controller
- 参数为包名:包下的所有Controller,可指定多个如:
@ControllerAdvice(basePackages={"cn.ken.test1", "cn.ken.test2"})
- 参数为注解:可以自定义注解后匹配所有加了该注解的Controller,如:
@ControllerAdvice(annotations={MyAnnotation.class})
此注解是一个在类上声明的注解,是aop思想的一种实现,主要通过配合@ExceptionHandler、@InitBinder 或 @ModelAttribute这三个注解以实现全局异常处理、全局数据绑定和全局数据预处理
@ExceptionHandler注解指定要捕获的异常类型
@ControllerAdvice
public class AllControllerAdvice {
private static Logger logger = LoggerFactory.getLogger(AllControllerAdvice.class);
/**
* 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
}
/**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
*/
@ModelAttribute
public void addAttributes(Model model) {
}
/**
* 捕捉shiro的异常
* @param e
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(ShiroException.class)
@ResponseBody
public ResponseModel<String> handleShiroException(ShiroException e) {
return ResponseHelper.failedWith(null, CodeEnum.IDENTIFICATION_ERROR.getCode(),CodeEnum.IDENTIFICATION_ERROR.getMsg());
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(AuthenticationException.class)
@ResponseBody
public ResponseModel<String> handleShiroException(AuthenticationException e) {
return ResponseHelper.failedWith(null, CodeEnum.IDENTIFICATION_ERROR.getCode(),CodeEnum.IDENTIFICATION_ERROR.getMsg());
}
/**
* 捕捉BusinessException自定义抛出的异常
* @return
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BusinessException.class)
@ResponseBody
public ResponseModel handleBusinessException(BusinessException e) {
String message = e.getMessage();
if(message.indexOf(":--:") > 0){
String[] split = message.split(":--:");
return ResponseHelper.failedWith(null,split[1],split[0]);
}
return ResponseHelper.failedWith(null,CodeEnum.DATA_ERROR.getCode(),message);
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(TemplateInputException.class)
@ResponseBody
public ResponseModel<String> handleTemplateInputException(TemplateInputException e) {
return ResponseHelper.failed2Message(CodeEnum.USER_NO_PERMITION.getMsg());
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = ParamJsonException.class)
@ResponseBody
public ResponseModel<String> handleParamJsonException(Exception e) {
if(e instanceof ParamJsonException) {
logger.info("参数错误:"+e.getMessage());
return ResponseHelper.failed2Message("参数错误:"+ e.getMessage());
}
return ResponseHelper.failedWith(null,CodeEnum.PARAM_ERROR.getCode(),e.getMessage());
}
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(value = HttpMessageNotReadableException.class)
@ResponseBody
public ResponseModel<String> handleParamJsonException(HttpMessageNotReadableException e) {
if(e instanceof HttpMessageNotReadableException) {
logger.info("参数错误:"+e.getMessage());
return ResponseHelper.failed2Message("参数错误:"+ e.getMessage());
}
return ResponseHelper.failedWith(null,CodeEnum.PARAM_ERROR.getCode(),e.getMessage());
}
/**
* 全局异常捕捉处理
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.OK)
public ResponseModel<String> errorHandler(Exception ex) {
ex.printStackTrace();
logger.error("接口出现严重异常:{}", ex.getMessage());
return ResponseHelper.failed2Message(CodeEnum.ERROR.getMsg());
}
}
可在类下定义多个@ExceptionHandler以对不同异常进行不同的处理
ExceptionHandler的处理顺序是由异常匹配度来决定的,首先找到可以匹配异常的所有ExceptionHandler,然后对其进行排序(深度比较器,通过递归不停地判断父异常是否为目标异常来取得最终的深度),取深度最小,即匹配度最高的那个
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Ken·勇者の小栈
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果