Spring Boot拦截所有异常处理程序

ada*_*shr 5 java spring spring-mvc spring-boot

我正在尝试执行一些通用逻辑,这些逻辑适用@ExceptionHandler于代码中的所有。我知道我可以写一个HandlerInterceptor拦截幸福的道路。但是我想了解异常处理的生命周期,以便可以在呈现错误响应之前执行一些常见的逻辑,例如日志记录。

无论如何,在Spring Boot / Spring MVC中有这样做吗?如果可能的话,我想避免为此编写一个servlet过滤器。

Dav*_*era 6

有一种方法@RestControllerAdvice@ExceptionHandler,一个例子:

@RestControllerAdvice
public class GlobalControllerExceptionHandler {

    @ExceptionHandler(value = {DeniedPermissionException.class})
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public String deniedPermissionException(DeniedPermissionException ex) {
        return "Denied permission";
    }

    @ExceptionHandler(value = {ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String constraintViolationException(ConstraintViolationException ex) {
        return "Bad request";
    }

    @ExceptionHandler(value = {Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String internalServerError(Exception ex) {
         return "Internal error";
    }
}
Run Code Online (Sandbox Code Playgroud)

*DeniedPermissionException是自定义异常。


ada*_*shr 5

我有一个解决方案。这是关于使用HandlerInterceptor.afterCompletion方法。但是,此方法文档中有一行指出:

注意:只有在此拦截器的 preHandle 方法成功完成并返回 true 时才会调用!

所以诀窍是也实现preHandle并让它返回true

现在我的拦截器看起来像这样:

@Component
public class MyInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // perform common logic here
    }
}
Run Code Online (Sandbox Code Playgroud)

但是要注意的一件事是,如果您有一系列拦截器和一个拦截器,然后再抛出异常,则该拦截器将没有机会执行。因此,如果我们重新排序拦截器链,使其MyInterceptor位于顶部,它将拦截所有请求。