异常处理流程
业务中存在运行时异常和业务逻辑异常,前者不运行时很难察觉,后者在遍及业务时就可以定义出来,因此异常分为不可预知异常和可知异常。流程如下:
- 自定义全局异常类,使用
@ControllerAdvice
,控制器增强 - 自定义错误代码及错误信息,两种异常最终会采用统一的信息格式来表示,错误代码+错误信息。
- 对于可预知的异常由程序员在代码中主动抛出,由
SpringMVC
统一捕获。 - 不可预知异常通常是由于系统出现bug、或一些外界因素(如网络波动、服务器宕机等),异常类型为
RuntimeException
类型(运行时异常)。
@ControllerAdvice
该注解为统一异常处理的核心
是一种作用于控制层的切面通知(Advice),该注解能够将通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法收集到一个类型,并应用到所有控制器上
该类中的设计思路:
-
使用@ExceptionHandler注解捕获指定或自定义的异常;
-
使用@ControllerAdvice集成@ExceptionHandler的方法到一个类中;
-
必须定义一个通用的异常捕获方法,便于捕获未定义的异常信息;
-
自定一个异常类,捕获针对项目或业务的异常;
-
异常的对象信息补充到统一结果枚举中;
PS:
1、配置返回类 BaseResults
详解:https://blog.csdn.net/W_Meng_H/article/details/104995823
2、少使用e.printStackTrace(), 因为e.printStackTrace() 语句要产生的字符串记录的是堆栈信息,太长太多,内存被填满了!
详解:https://my.oschina.net/sxgkwei/blog/825700
一、自定义全局异常类
@Getter
@Setter
@ToString
public class MengException extends RuntimeException {
private Integer code;
public MengException(Integer code, String message) {
super(message);
this.code = code;
}
public MengException(BaseResultsEnum baseResultsEnum ) {
super(baseResultsEnum .getMessage());
this.code = baseResultsEnum .getCode();
}
}
二、统一异常处理类
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**-------- 通用异常处理方法 --------**/
@ExceptionHandler(Exception.class)
@ResponseBody
public BaseResults error(Exception e) {
// 记录日志
log.error("出现异常:{}",e.getMessage());
// 通用异常结果
return new BaseResultsUtil().error(BaseResultsEnum.UNKNOWN_ERROR.getCode(),
BaseResultsEnum.UNKNOWN_ERROR.getMessage());
}
/**-------- 指定异常处理方法 --------**/
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public BaseResults error(NullPointerException e) {
log.error("出现异常:{}",e.getMessage());
return new BaseResultsUtil().error(BaseResultsEnum.NULL_POINT.getCode(),
BaseResultsEnum.NULL_POINT.getMessage());
}
@ExceptionHandler(HttpClientErrorException.class)
@ResponseBody
public BaseResults error(IndexOutOfBoundsException e) {
log.error("出现异常:{}",e.getMessage());
return new BaseResultsUtil().error(BaseResultsEnum.INDEX_OUT.getCode(),
BaseResultsEnum.INDEX_OUT.getMessage());
}
/**-------- 自定义定异常处理方法 --------**/
@ExceptionHandler(MengException.class)
@ResponseBody
public BaseResults error(MengException e) {
log.error("出现异常:{}",e.getMessage());
return new BaseResultsUtil().error(e.getCode(),
e.getMessage());
}
}
三、Swagger2 测试
配置 Swagger2 :https://blog.csdn.net/W_Meng_H/article/details/105034480