项目中统一异常处理
- 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());}
}