在Spring Boot中使用切面统一处理自定义的异常
最近我们将项目的一个单独模块提取了一个微服务,这个微服务主要负责其他系统的接入。目的是发布主项目的时候不会影响到其他系统接入。在提取出的微服务中,需要定义一个正常返回的报文和异常返回的报文。正常返回报文就是正常业务返回的数据报文,异常返回报文我这里定义为比如一些校验异常或是权限异常等等,这里不包括程序出现的异常,比如数据库出错这些。我暂时是这样定义的。大家有好的方式也可以一块讨论。
正常的报文:正常的报文比较松散,我指定为自己去定义报文格式。不过基本有这两个字段
{ "requestId": "ed93f3cb-f35e-473f-b9f3-0d451b8b79c6", "data": { ... } }
requestId是为了更容易跟踪程序错误
异常的报文:
{ "requestId": "ed93f3cb-f35e-473f-b9f3-0d451b8b79c6", "error": { "code": "NotNullAndLengthErr.waybillNo", "msg": "运单号不为空且长度需为15位或12位" } }
在程序中主要处理异常的报文,多为对权限的校验,业务的校验,我将这些校验出错的情况用异常的方式抛出,然后在切面中统一处理自定义的异常
public class OccpDdsRuntimeException extends RuntimeException { private ErrorCodeEnum errorCodeEnum; public ErrorCodeEnum getErrorCodeEnum() { return errorCodeEnum; } public OccpDdsRuntimeException(ErrorCodeEnum errorCodeEnum) { super(errorCodeEnum.getErrMsg()); this.errorCodeEnum = errorCodeEnum; } }
这里的ErrorCodeEnum是我自定义的Enum类,为的是定义一些错误,比如校验错误,权限错误等
public enum ErrorCodeEnum { NotNullAndLengthErrWaybillNo("NotNullAndLengthErr.waybillNo", "运单号不为空且长度需为15位或12位", 420); private String errCode; private String errMsg; private int httpStatus; ErrorCodeEnum(String errCode, String errMsg, int httpStatus) { this.errCode = errCode; this.errMsg = errMsg; this.httpStatus = httpStatus; } public String getErrCode() { return errCode; } public String getErrMsg() { return errMsg; } public int getHttpStatus() { return httpStatus; } }
下面看一下真正的绝学,在切面中统一处理自定义的异常以达到返回异常的报文
/** * 全局异常处理 */ @ControllerAdvice public class OccpDdsExceptionHandler { private static Logger LOG = LoggerFactory.getLogger(OccpDdsExceptionHandler.class); @ExceptionHandler(OccpDdsRuntimeException.class) //1 @ResponseBody //2 public Map<String, Object> handleException(OccpDdsRuntimeException ex, HttpServletResponse response) { Map<String, Object> responseBody = new HashMap<>(); String requestId = getRequestId(); if (ex instanceof OccpDdsRuntimeException) { //这里进行组装报文的操作 } //返回报文 return responseBody; } private String getRequestId() { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); return (String)request.getAttribute(REQUEST_ID); } }
上面的代码中注释第一行完全可以自己去组装想要的报文,1处定义了捕获哪个异常,2表示返回的对象类型。
这样就可以测试一下项目当抛出自定义异常了
上一篇:
IDEA上Java项目控制台中文乱码