一、统一异常处理的作用
在web应用中,请求处理时,出现异常是非常常见的。所以当应用出现各类异常时,进行异常的统一捕获或者二次处理(比如空指针异常或sql异常正常是不能外抛)是非常必要的,然后右统一异常处理方法统一返给前端。
对于非自定义的异常,在统一异常处理方法中,会转化为约定了响应的参数格式,如code(非0代表异常)、message,调用方根据错误码进行自己的业务逻辑。
二、统一异常处理方案一
@RestControllerAdvice和@ExceptionHandler的方式
@RestControllerAdvice public class BaseControllerAdvice { private static final Logger logger = LoggerFactory.getLogger(BaseControllerAdvice.class); public static final Pattern ERROR_MESSAGE_PATTERN = Pattern.compile("\\[(\\d{4})\\] (.*)"); public BaseControllerAdvice() { } @ExceptionHandler public ApiResponse globalExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) { logger.error("检测到未捕捉异常:IP:{} invoke url:{} Exception:{}", new Object[]{request.getRemoteAddr(), request.getRequestURL(), ex.getClass().toGenericString(), ex});
//ApiResponse为自定义异常类 ApiResponse apiResponse = new ApiResponse(ApiResponseCodeEnum.SYSTEM_EXCEPTION); if (ex instanceof ApiException) { Integer code = ((ApiException)ex).getCode(); return new ApiResponse(code, ex.getMessage()); } else { if (StringUtils.isNotBlank(ex.getMessage())) { Matcher matcher = ERROR_MESSAGE_PATTERN.matcher(ex.getMessage()); if (matcher.matches()) { logger.error(ex.getMessage(), ex); return apiResponse; } } return apiResponse; } } }
三、统一异常处理方案二
HandlerExceptionResolver的方式
@Component public class GlobalHandlerExceptionResolver implements HandlerExceptionResolver { private static final Logger logger = LoggerFactory.getLogger(BaseControllerAdvice.class); public static final Pattern ERROR_MESSAGE_PATTERN = Pattern.compile("\\[(\\d{4})\\] (.*)"); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); logger.error("检测到未捕捉异常:IP:{} invoke url:{} Exception:{}", new Object[]{request.getRemoteAddr(), request.getRequestURL(), ex.getClass().toGenericString(), ex}); ApiResponse apiResponse = new ApiResponse(ApiResponseCodeEnum.SYSTEM_EXCEPTION); if (ex instanceof ApiException) { Integer code = ((ApiException)ex).getCode(); apiResponse =new ApiResponse(code, ex.getMessage()); } else { if (StringUtils.isNotBlank(ex.getMessage())) { Matcher matcher = ERROR_MESSAGE_PATTERN.matcher(ex.getMessage()); if (matcher.matches()) { logger.error(ex.getMessage(), ex); } } } modelAndView.setView(new MappingJackson2JsonView()); modelAndView.addObject("code",apiResponse.getCode()); modelAndView.addObject("message",apiResponse.getMessage()); return modelAndView; } }