springboot filter 异常处理

需求

最近有个需求,要在 filter 层中对用户进行自定义的校验,验证失败返回异常信息。
最开始不了解 springboot 异常机制,就直接抛出异常,后面有人反馈,说返回的是 html 信息,希望能统一走 json 格式。
百度了一下 springboot 的异常处理,发现 Filter 中抛出的异常无法被@ControllerAdvice处理,又开始百度解决方案,大多是 try catch捕捉之后转到对应的控制层,再抛出,就感觉不太对劲,又谷歌一下翻了半天,找到一个还不错的解决方案,于是记录一下

解决方案

异常错误会被默认重定向至/error 进行处理,重写/error 的 Controller 后再将异常抛出,由对应的@ExceptionHandler 处理即可,代码如下:

@Slf4j
@RestControllerAdvice
@Controller
public class ServiceExceptionHandler implements ErrorController {
    private static final String PATH_DEFAULT = "/error";

    @RequestMapping(PATH_DEFAULT)
    public void handleError(HttpServletRequest request) throws Throwable {
      final String error = "javax.servlet.error.exception";
      Object err = request.getAttribute(error);
      if (ObjectUtil.isNotNull(err)) {
          Throwable e = (Throwable) err;
          log.error("filter有异常,请求日志:{},异常信息:{}", request.getContextPath(), e.getMessage());
          throw e;
      }
    }

    @Override
    public String getErrorPath() {
        return PATH_DEFAULT;
    }

    // CustomException为自定义异常
    @ExceptionHandler(CustomException.class)
    public Result handleUnAuthorize(UnAuthenticationException e){
        log.error("异常信息:{}", e.getMessage());
        return Result.error(e.getMessage());
    }
}

经过测试,成功响应封装的 json 数据

参考文章

SpringBoot 全局统一处理异常(含 Filter)

Q.E.D.


梦醒花犹存,铁甲依然在