@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标签,用于扫描异常处理类

原文地址:https://www.cnblogs.com/deolin/p/7871290.html