OncePerRequestFilter - 处理用@ResponseStatus 注释的异常

OncePerRequestFilter - handling exceptions annotated with @ResponseStatus

我正在寻找一种方法来在数据库中记录我的所有请求和响应(1 条记录 = 1 条请求 + 1 条响应)。 我的用例详细信息:

  1. 在数据库中记录请求URL、参数、IP、开始日期等
  2. 更新数据库记录(当请求完成时)并保存响应, 例外情况、结束日期等

我正在尝试使用自定义 OncePerRequestFilter,它几乎可以正常工作。但是我在处理用注释 @ResponseStatus 注释的异常时遇到问题。这种异常(在控制器中抛出)我无法在我的自定义 doFilter 方法中捕获。你知道有什么方法可以在过滤器中捕获这些异常吗?除非我应该以其他方式做到这一点?

审计过滤器:

@Component
public class AuditFilter extends OncePerRequestFilter {

    private Logger logger = Logger.getLogger(AuditFilter.class.getName());
    private RequestAuditRepository repository;


    AuditFilter(RequestAuditRepository repository) {
        this.repository = repository;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        doFilterWrapped(wrapRequest(request), wrapResponse(response), filterChain);
    }

    private void doFilterWrapped(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, FilterChain filterChain)
            throws ServletException, IOException {

        RequestAuditLog requestAuditLog = new RequestAuditLog();
        String catchedExceptionMsg = null;
        try {
            beforeRequest(requestAuditLog, request); 
            filterChain.doFilter(request, response);
        }
        catch (Exception e) {
            // Not called when exception with @ResponStatus annotation throwed
            catchedExceptionMsg = e.getMessage();
            throw e;
        }
        finally {
            afterRequest(requestAuditLog, catchedExceptionMsg, request, response);
            response.copyBodyToResponse();
        }
    }

    ...

}

BadRequestException:

@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException {
    public BadRequestException(String message) {
        super(message);
    }
}

我认为 BadRequestException 甚至在您的自定义过滤器被触发之前就已处理,因此您无法在过滤器中捕获此异常。

你可以做的是你自己写ExceptionHandler到你的过滤器并在那里记录你的东西。

@ControllerAdvice
public class MyExceptionHandler {

  @ExceptionHandler(BadRequestException.class)
  public void handleError(BadRequestException ex) {
     // do your stuff here
  }

}