@ControllerAdvice 和 @ExceptionHandler
@ExceptionHandler的作用是把对不同异常处理抽取到不同的方法中。
@ControllerAdvice的作用是把控制器中 @ExceptionHandler、@InitBinder、@ModelAttribute方法抽取到一个专门的类当中。
@ControllerAdvice 和 @ExceptionHandler结合之后可以做控制层的统一异常处理
以前做法是,控制层是捕获一切异常,然后分类处理它们,如以下的例子:
@RequestMapping(value = "demo1", method = RequestMethod.POST) @ResponseBody public ResultBean demo1() { try { studentService.createOneStudent(); teacherService.createOneTeacher(); studentService.joinTeacher(); } catch (StudentExistsException e1) { return new ResultBean(false, "学生已经存在。"); } catch (TeacherExistsException e2) { return new ResultBean(false, "教师已经存在。"); } catch (AbnormalDataException e3) { log.error("异常数据越过前端校验"); return new ResultBean(false, "请重试。"); } catch (NetworkException e4) { return new ResultBean(false, "网络错误,请重试。"); } catch (Exception e5) { log.error(e5.getMessage()); return new ResultBean(false, "请重试。"); } return new ResultBean(true, null); }
现在可以把异常处理抽取出来,不让异常处理的代码与调用业务层分发任务的代码搅合在一起。
@RequestMapping(value = "demo2", method = RequestMethod.POST) @ResponseBody // 异常直接往外抛 public ResultBean demo2() throws Exception { studentService.createOneStudent(); teacherService.createOneTeacher(); studentService.joinTeacher(); return new ResultBean(true, null); }
追加一个异常处理类
@ControllerAdvice public class DemoExceptionHandler { private static final Logger log = LogManager.getLogger(ControllerExceptionHandler.class); @ExceptionHandler(StudentExistsException.class) @ResponseBody public ResultBean processStudentExistsException(NativeWebRequest request, StudentExistsException e) { return new ResultBean(false, "学生已经存在。"); } @ExceptionHandler(TeacherExistsException.class) @ResponseBody public ResultBean processTeacherExistsException(NativeWebRequest request, TeacherExistsException e) { return new ResultBean(false, "教师已经存在。"); } @ExceptionHandler(AbnormalDataException.class) @ResponseBody public ResultBean processAbnormalDataException(NativeWebRequest request, AbnormalDataException e) { log.error("异常数据越过前端校验"); return new ResultBean(false, "请重试。"); } @ExceptionHandler(NetworkException.class) @ResponseBody public ResultBean processNetworkException(NativeWebRequest request, NetworkException e) { return new ResultBean(false, "网络错误,请重试。"); } @ExceptionHandler(Exception.class) @ResponseBody public ResultBean processException(NativeWebRequest request, Exception e) { log.error(e5.getMessage()); return new ResultBean(false, "请重试。"); } }
最后,必须在SpirngMVC的配置文件里追加context:component-scan标签,用于扫描异常处理类