项目中统一异常处理
- 1.异常处理框架图
- 2.实现
1.异常处理框架图
异常处理除了输出在日志中,还需要提示给用户,前端和后端需要作一些约定:
- 错误提示信息统一以json格式返回给前端。
- 以HTTP状态码决定当前是否出错,非200为操作异常。
(1)如何规范异常信息?
代码中统一抛出项目的自定义异常类型,这样可以统一去捕获这一类或几类的异常。
规范了异常类型就可以去获取异常信息。
如果捕获了非项目自定义的异常类型统一向用户提示“执行过程异常,请重试”的错误信息。
(2)如何捕获异常?
代码统一用try/catch
方式去捕获代码比较臃肿,可以通过SpringMVC
提供的控制器增强类统一由一个类去完成异常的捕获。
2.实现
(1)首先,添加基础依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
(2)定义通用的异常信息
public enum CommonError {
UNKOWN_ERROR("执行过程异常,请重试。"),
PARAMS_ERROR("非法参数"),
OBJECT_NULL("对象为空"),
QUERY_NULL("查询结果为空"),
REQUEST_NULL("请求参数为空");
private String errMessage;
public String getErrMessage() {
return errMessage;
}
private CommonError( String errMessage) {
this.errMessage = errMessage;
}
}
(3)自定义异常类
public class XueChengPlusException extends RuntimeException {
private String errMessage;
public XueChengPlusException() {
super();
}
public XueChengPlusException(String errMessage) {
super(errMessage);
this.errMessage = errMessage;
}
public String getErrMessage() {
return errMessage;
}
public static void cast(CommonError commonError){
throw new XueChengPlusException(commonError.getErrMessage());
}
public static void cast(String errMessage){
throw new XueChengPlusException(errMessage);
}
}
(4)响应用户的统一类型
public class RestErrorResponse implements Serializable {
private String errMessage;
public RestErrorResponse(String errMessage){
this.errMessage= errMessage;
}
public String getErrMessage() {
return errMessage;
}
public void setErrMessage(String errMessage) {
this.errMessage = errMessage;
}
}
(5)全局异常处理器
从 Spring 3.0 - Spring 3.2
版本之间,对 Spring
架构和 SpringMVC
的Controller
的异常捕获提供了相应的异常处理。
@ExceptionHandler
。Spring3.0
提供的标识在方法上或类上的注解,用来表明方法的处理异常类型。@ControllerAdvice
。Spring3.2
提供的新注解,从名字上可以看出大体意思是控制器增强,在项目中来增强SpringMVC
中的Controller
。通常和@ExceptionHandler
结合使用,来处理SpringMVC
的异常信息。@ResponseStatus
。Spring3.0
提供的标识在方法上或类上的注解,用状态代码和应返回的原因标记方法或异常类。
调用处理程序方法时,状态代码将应用于HTTP
响应。
通过上面的两个注解便可实现微服务端全局异常处理,具体代码如下:
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(XueChengPlusException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse customException(XueChengPlusException e) {
log.error("【系统异常】{}",e.getErrMessage(),e);
return new RestErrorResponse(e.getErrMessage());
}
@ResponseBody
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(Exception e) {
log.error("【系统异常】{}",e.getMessage(),e);
return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
}
}