软件开发过程中,不可避免的是需要处理各种异常,就我自己来说,至少有一半以上的时间都是在处理各种异常情况,所以代码中就会出现大量的try {...} catch {...} finally {...} 代码块,不仅有大量的冗余代码,而且还影响代码的可读性
我们可以不显式的处理异常,优雅的处理异常吗
Spring在3.2版本增加了一个注解@ControllerAdvice,可以与@ExceptionHandler、@InitBinder、@ModelAttribute 等注解注解配套使用
不过跟异常处理相关的只有注解@ExceptionHandler,从字面上看,就是 异常处理器 的意思,其实际作用也是:若在某个Controller类定义一个异常处理方法,并在方法上添加该注解,那么当出现指定的异常时,会执行该处理异常的方法,其可以使用springmvc提供的数据绑定,比如注入HttpServletRequest等,还可以接受一个当前抛出的Throwable对象。
在独立的某个地方,比如单独一个类,定义一套对各种异常的处理机制,然后在类的签名加上注解@ControllerAdvice,统一对 不同阶段的、不同异常 进行处理。这就是统一异常处理的原理。
注意到上面对异常按阶段进行分类,大体可以分成:进入Controller前的异常 和 Service 层异常,具体可以参考下图:

- /**
- * 全局异常处理
- */
- //表示处理带有RestController Controller这两种注解的类
- @ControllerAdvice(annotations = {RestController.class, Controller.class})
- @ResponseBody
- @Slf4j
- public class GlobalExceptionHandler {
-
- /**
- * 异常处理方法
- * 该异常可以捕获sql中的insert中unique字段重复的异常
- * @return
- */
- @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
- public R
exceptionHandler(SQLIntegrityConstraintViolationException ex){ - log.error(ex.getMessage());
-
- if(ex.getMessage().contains("Duplicate entry")){
- String[] split = ex.getMessage().split(" ");
- String msg = split[2] + "已存在";
- return R.error(msg);
- }
-
- return R.error("未知错误");
- }
-
- /**
- * 异常处理方法
- * @return
- */
- @ExceptionHandler(CustomException.class)
- public R
exceptionHandler(CustomException ex){ - log.error(ex.getMessage());
-
- return R.error(ex.getMessage());
- }
-
- }