全局Controller异常处理

先导

通常在service层捕获dao层异常,以回滚数据。 因此,在controller层就需要捕获service层异常,防止用户查看到内部错误。使用try-catch代码块捕获异常不仅使代码更友好,也在一定程度上提高了安全性。 然而,每个controller都需要重复的使用try-catch代码块不满足重构原则,显得不那么优雅,而且在维护时也很不方便。因此全局的controller异常捕获就是对controller层重构的一种思路。

实现思路

  1. 创建一个GlobalExceptionHandler类,用来处理全局的异常。
  2. 在该类之上,添加@ControllerAdvice注解,且需要确保该类能被扫描到。
  3. 除了Exception系统自带的异常,最好还有自定义的异常,例如BusinessException
  4. 创建一个方法,捕获全局异常:
    /**
     * 处理所有不可知异常
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    MessageDTO handleException(Exception e){
        log.error("error:", e);
        return MessageDTO.build().error(500, "internal error");
    }
  1. 创建一个方法捕获已知的特定异常:
    /**
     * 处理已知特定异常
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    MessageDTO handleBusinessException(BusinessException e){
        log.error("error:", e);
        return MessageDTO.build().error(404, e.getMessage());
    }
  1. 在controller层就不需要做try-catch捕获异常,所有的controller层的异常都会被@ControllerAdvice捕获

其他

在controller层还经常使用validation做数据的验证,可以搭配使用。直接在格式不匹配时,抛出特定异常,通过@ControllerAdvice捕获后统一输出;或者使用自建的BeanValidator校验后,造错误响应对象返回。

代码

https://github.com/LudanLink/blog-tpl