实现原理:
异常结果拦截逻辑
contorller层统一异常处理组件是通过spring的ControllerAdvice和ExceptionHandler来 拦截系统controller方法执行抛异常的请求,然后对异常结果做统一的封装,底层还是spring的aop实现。
异常处理逻辑:
配置文件指定异常处理策略:在系统启动时,加载exceptionCode.properties配置文件来 指定对特定异常进行统一错误响应码、统一错误消息的封装策略(通过 exceptionCode.properties指定的方式后续需要去掉)。 继承BuzzErrorException指定异常处理策
异常处理类解析: 业务异常类BuzzErrorException
在我们进行业务处理时,绝大多数时不会对业务执行过程中抛出的异常进行捕获后进行特殊 的业务处理,而是直接抛出,所以BuzzErrorException通过基础RuntimeException,这样 业务系统抛出的业务异常不要每次都去捕获后又原封不动抛出,或在方法签名上加上一个很长的异常列表。 在实现自己的业务异常类时需要继承BuzzErrorException,并且可以通过errorCode来指定返回给前端的错误码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
public class BuzzErrorException extends RuntimeException { private int errorCode = 500;
public BuzzErrorException() { this("未知异常"); }
public BuzzErrorException(String message) { super(message); }
public BuzzErrorException(String message, Throwable cause) { super(message, cause); }
public BuzzErrorException(Throwable cause) { super(cause); }
public BuzzErrorException(int errorCode) { this(errorCode,"未知异常"); }
public BuzzErrorException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); }
public BuzzErrorException(int errorCode, String message) { super(message); this.errorCode = errorCode; }
public BuzzErrorException(int errorCode,String message, Throwable cause) { super(message, cause); this.errorCode = errorCode; }
public BuzzErrorException(int errorCode,Throwable cause) { super(cause); this.errorCode = errorCode; }
public int getErrorCode() { return errorCode; }
public void setErrorCode(int errorCode) { this.errorCode = errorCode; } }
|
controller统一业务异常处类:GlobalExceptionHandler
统一异常处理入口方法: 在拦截到controller方法执行异常时,会通过执行所抛出的异常生成异常信息和响应错误码 包装到GlobalExceptionHandler.ErrorMessage 类中,然后包装成响应结果对象返回给前端:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @ExceptionHandler(value = Exception.class) public ModelAndView defaultErrorHandler(HttpServletRequest request,HttpServletResponse response, Exception ex) throws Exception { logger.error(ex.getMessage(), ex); ErrorMessage mess = getMessage(ex); ResponseEntity result = returnException(mess); try { response.setContentType("text/plain; charset=UTF-8"); response.getWriter().write(JSONObject.toJSONString(result)); } catch (IOException e) { logger.error("返回异常",e.getMessage()); } return new ModelAndView(); }
|
根据异常对象生成异常结果对象ErrorMessage:
生成异常结果对象的步骤如下:
1.通过配置文件指定的异常处理策略来生成异常结果对象;
2.如果是BuzzErrorException的子类,则通过BuzzErrorException的errorCode和 message来生成异常结果对象;
3.如果不为BuzzErrorException的子类但为包装异常类,则通过包装的异常类生成异常结果对象;
4.如果为其他情况,就按照Exception类生成默认的系统异常结果对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| private ErrorMessage getMessage(Throwable th) { ErrorMessage mess = null; if (th instanceof BuzzErrorException){ BuzzErrorException buzzErrorException = (BuzzErrorException)th; mess = new ErrorMessage(buzzErrorException.getErrorCode(),buzzErrorException.getMessage()); } else if (th instanceof BncErrorException) { BncErrorException bncErrorException = (BncErrorException)th; mess = new ErrorMessage(4002,bncErrorException.getMessage()); } else if (th.getCause() != null){ mess = getMessage(th.getCause()); }else { ErrorMsgDetail errorMsgDetail = getErrorMsgDetail(th); String exceptionMsg = errorMsgDetail.getExceptionMsg(); boolean hasMsg = StringUtils.isBlank(exceptionMsg) || exceptionMsg.equals("null"); mess = new ErrorMessage(500, hasMsg ? "系统异常,请联系管理员!" : exceptionMsg, errorMsgDetail); } return mess; }
|