使用SpringBoot内置的@ControllerAdvice和@ExceptionHandler进行异常处理:
@ControllerAdvice:使用该注解即表示开启全局异常捕获,可自定义basePackages,用于标示异常捕获范围;@ExceptionHandler:定义捕获异常的类型
Asuka中预置了GlobalExceptionHandler,捕获com.asuka包内的异常。
@ControllerAdvice(basePackages = "com.asuka")public class GlobalExceptionHandler {private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(BusinessException.class)public String businessExceptionHandler(BusinessException ex, HttpServletRequest request, HttpServletResponse response){logger.error(ex.getMessage(), ex);return doHandler("error/500.html", 500, ex.getMessage(), ex.toString(), request, response);}@ExceptionHandler(AccessDeniedException.class)public String AccessDeniedException(AccessDeniedException ex, HttpServletRequest request, HttpServletResponse response) {return doHandler("error/403.html", 403, ex.getMessage(), ex.toString(), request, response);}@ExceptionHandler(AuthenticationException.class)public String AuthenticationException(AuthenticationException ex, HttpServletRequest request, HttpServletResponse response) {return doHandler("error/403.html", 403, ex.getMessage(), ex.toString(), request, response);}@ExceptionHandler(IllegalArgumentException.class)public String IllegalArgumentException(IllegalArgumentException ex, HttpServletRequest request, HttpServletResponse response) {return doHandler("error/500.html", Constants.RESULT_ERROR_CODE, ex.getMessage(), ex.toString(), request, response);}@ExceptionHandler(NullPointerException.class)public String NullPointerException(NullPointerException ex, HttpServletRequest request, HttpServletResponse response) {logger.error(ex.getMessage(), ex);return doHandler("error/500.html", Constants.RESULT_ERROR_CODE, ex.getMessage(), ex.toString(), request, response);}@ExceptionHandler(Exception.class)public String errorHandler(Exception ex, HttpServletRequest request, HttpServletResponse response) {logger.error(ex.getMessage(), ex);if (ex instanceof IException) {return doHandler("error/500.html", ((IException) ex).getCode(), ex.getMessage(), ex.toString(), request, response);}return doHandler("error/500.html", Constants.RESULT_ERROR_CODE, "系统错误", ex.toString(), request, response);}/*** 处理错误,ajax返回json,非ajax跳转页面*/private String doHandler(String url, Integer code, String msg, String error, HttpServletRequest request, HttpServletResponse response) {if (isAjax(request)) {cross(response); // 支持跨域response.setContentType("application/json;charset=utf-8");try {PrintWriter out = response.getWriter();out.write(JSON.toJSONString(JsonResult.error(code, msg).put("error", error)));out.flush();out.close();} catch (IOException e) {e.printStackTrace();}return null;}return url;}/*** 判断是不是ajax请求*/private boolean isAjax(HttpServletRequest request) {String xHeader = request.getHeader("X-Requested-With");return (xHeader != null && xHeader.contains("XMLHttpRequest"));}/*** 支持跨域请求*/private void cross(HttpServletResponse response) {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, Authorization");}}
如果要针对各个服务捕获不同的异常,可以新建ExceptionHandler,区分不同的@ControllerAdvise的basePackages即可。
