一、简介
@RestControllerAdvice 是Controller的切面, 结合 @ExceptionHandler 实现全局异常捕获及处理。
@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { /** * desc 请求参数合法性校验 * @param exception * @return */ @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) public String validationBodyException(MethodArgumentNotValidException exception){ StringBuffer buffer = new StringBuffer(); BindingResult result = exception.getBindingResult(); if (result.hasErrors()) { List<ObjectError> errors = result.getAllErrors(); errors.forEach(p ->{ FieldError fieldError = (FieldError) p; log.error("Data check failure : object{"+fieldError.getObjectName()+"},field{"+fieldError.getField()+ "},errorMessage{"+fieldError.getDefaultMessage()+"}"); buffer.append(fieldError.getDefaultMessage()).append(","); }); } BaseResponse response = new BaseResponse(BaseCodeEnum.INVALID_PARAM); response.setRespMsg(buffer.toString().substring(0, buffer.toString().length()-1)); return JSONObject.toJSONString(response); } /** * 请求参数转换异常 * @param exception * @return */ @ExceptionHandler(HttpMessageConversionException.class) public String parameterTypeException(HttpMessageConversionException exception){ log.error(exception.getMessage()); return ResultUtil.returnException(BaseCodeEnum.INVALID_PARAM); } /** * 缺少参数 * @param ex * @return */ @ResponseBody @ExceptionHandler( ServletRequestBindingException.class) public String validationBodyException(Exception ex){ log.error(ex.getMessage()); return ResultUtil.returnException(BaseCodeEnum.MISSING_PARAMS); } /** * @param requet * @param e * @return * @throws Exception */ @ExceptionHandler(value = Exception.class) @ResponseBody public BaseResponse errorHandler(HttpServletRequest requet, Exception e) throws Exception { BaseResponse response = new BaseResponse(); log.error(e.getMessage(), e); if (e instanceof CommonException) { CommonException commonException = (CommonException) e; response.setRespCode(commonException.getResp_code()); response.setRespMsg(commonException.getResp_msg()); } else if (e instanceof CommonRuntimeException) { CommonRuntimeException commonRuntimeException = (CommonRuntimeException) e; response.setRespCode(commonRuntimeException.getResp_code()); response.setRespMsg(commonRuntimeException.getResp_msg()); } else { response = new BaseResponse(BaseCodeEnum.UNKNOWN_EXCEPTION); } return response; } }
二、错误整理
1、@RestControllerAdvice 未生效
原因:a、检查 scanBasePackage 配置的报路径,是否包含@RestControllerAdvice注释的类
b、检查注解是否添加
c、检查启动日志是否包含 @RestControllerAdvice 类信息
2、不同jar都包含@RestControllerAdvice 注解类,就一个生效
原因:@RestControllerAdvice 有加载顺序,先依赖的jar先加载其中的 @RestControllerAdvice 注解类,注解类里面的 @ExceptionHandler 也会按照顺序加载,如果加载到顶级异常 Exception 的捕获方法,那么后续加载的Exception的子类就会失效
解决方法 :调整jar包的映入顺序,把对顶级异常Exception的捕获放到最后引入