异常
1 . 异常的简介
程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。
2 .异常的划分
1) 可预知异常
我们经常会遇到以及处理一些异常,比如说 参数为空异常, 对数据库操作失败产生的异常等等我们将它划分为可预知异常
2) 不可预知异常
由框架抛出 在我们try catch 范围外的异常 , 比如 415 400
3 异常的处理
项目中我们通常处理异常的方式 往往是try catch 捕获异常, 再做一些逻辑代码 返回给前端 , 处理的异常越多 , 但大量的try catch 会造成代码的冗余 , 而且对代码的维护也不方便 , 所以下面请出我们的主角 来分别解决 可预知异常以及不可预知异常
1) 可预知异常的处理
首先我们传入一个空对象 ,模拟一个异常 查看运行的结果,
if(order.getPageType()== null){
KbqlException.kqbl(CommonCode.FAIL);
}
postman 请求后 响应500 , 可以看到在不进行try catch 条件下 ,没有进行处理的异常被直接抛出.
我们在测试一下try catch 后 ,
异常被捕获, 返回一些友好数据, 但是过多的try catch 造成的代码冗余怎么解决呢? 接下来解决可预知异常的处理话不多说直接贴代码
@ControllerAdvice //控制器增强
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
@ExceptionHandler(CustomExcption.class)
@ResponseBody
public ResponseResult customException(CustomExcption customExcption){
LOGGER.error("catch Exception :" +customExcption.getMessage());
ResultCode resultCode = customExcption.getResultCode();
return new ResponseResult(resultCode);
}
}
实现异常拦截的两个核心注解@ControllerAdvice 以及 @ExceptionHandler 下面简单介绍一下两个注解
@ControllerAdvice 是Spring3.2 中增加的新注解 Spring4之前,
@ControllerAdvice
在同一调度的Servlet中协助所有控制器。Spring4已经改变:@ControllerAdvice
支持配置控制器的子集,而默认的行为仍然可以利用。在Spring4中,
@ControllerAdvice
通过annotations()
, basePackageClasses()
, basePackages()
方法定制用于选择控制器子集
@ExceptionHandler 用于处理特定处理程序类和/或处理程序方法中的异常的注释。 注解中的参数是自定义的异常类,在第一行代码中抛出的KbqlException 就是CustomException (简单的封装了一下)
public class KbqlException {
public static void kqbl(ResultCode resultCode){
throw new CustomExcption(resultCode);
}
}
这样 当程序运行时 抛出CustomException 异常都会被全局异常处理类截获并处理. 大大减少try catch 代码的冗余. 以及降低代码的维护系数
2 不可预知异常处理
直接贴代码
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult exception(Exception exception){
LOGGER.error("catch Exception :" +exception.getMessage());
if (EXCEPTIONS == null){
EXCEPTIONS = builder.build();
}
ResultCode code = EXCEPTIONS.get(exception.getClass());
if (code != null){
return new ResponseResult(code);
}
return new ResponseResult(CommonCode.SERVER_ERROR);
}
可以看到这次@ExceptionHandler中的参数换成Exception ,它将捕获所有的Exception 并且执行相对应的逻辑 , 这里
做了一个ImmutableMap用来封装一些常见的异常
private static ImmutableMap<Class<? extends Throwable> ,ResultCode> EXCEPTIONS;
protected static ImmutableMap.Builder<Class<? extends Throwable>,ResultCode> builder = ImmutableMap.builder();
static{
builder.put(HttpMessageNotReadableException.class, CommonCode.PARAMS_NULL);
}
除了上面的这种方法去解决全局异常以外还可以用springMVC提供的 HandlerExceptionResolver 这个接口去解决 ()不同于注解形式此方法需要在springMVC中配置, 去吃口饭下次再写)