在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项目控制台中文乱码
