首页 > 解决方案 > 如何设置 OncePerRequestFilter 的实现以仅过滤一个端点

问题描述

我使用这个过滤器来记录我的请求和响应,它工作得很好,但我注意到我实际上不需要为我的所有端点使用这个过滤器——它会更有效,并且足以过滤和记录来自一个端点的请求。是否可以在方法中不使用 if 语句afterRequest?我搜索了很多,但几乎每个示例都与 spring security :(

@Slf4j
@Component
public class RequestAndResponseLoggingFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isAsyncDispatch(request)) {
            filterChain.doFilter(request, response);
        } else {
            doFilterWrapped(wrapRequest(request), wrapResponse(response), filterChain);
        }
    }

    protected void doFilterWrapped(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, FilterChain filterChain) throws ServletException, IOException {
        beforeRequest(request, response);
        try {
            filterChain.doFilter(request, response);
        }
        finally {
            afterRequest(request, response);
            response.copyBodyToResponse();
        }
    }

    protected void beforeRequest(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
        if (log.isInfoEnabled()) {
            val address = request.getRemoteAddr();
            val queryString = request.getQueryString();
            if (queryString == null) {
                log.info("{}> {} {}", address, request.getMethod(), request.getRequestURI());
            } else {
                log.info("{}> {} {}?{}", address, request.getMethod(), request.getRequestURI(), queryString);
            }
            Collections.list(request.getHeaderNames()).forEach(headerName ->
                Collections.list(request.getHeaders(headerName)).forEach(headerValue ->
                    log.info("{}> {}: {}", address, headerName, headerValue)));
            val content = request.getContentAsByteArray();
            if (content.length > 0) {
                log.info("{}>", address);
                try {
                    val contentString = new String(content, request.getCharacterEncoding());
                    Stream.of(contentString.split("\r\n|\r|\n")).forEach(line -> log.info("{}> {}", address, line));
                } catch (UnsupportedEncodingException e) {
                    log.info("{}> [{} bytes body]", address, content.length);
                }
            }
            log.info("{}>", address);
        }
    }

    protected void afterRequest(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response) {
        if (log.isInfoEnabled()) {
            val address = request.getRemoteAddr();
            val status = response.getStatus();
            log.info("{}< {} {}", address, status, HttpStatus.valueOf(status).getReasonPhrase());
            response.getHeaderNames().forEach(headerName ->
                response.getHeaders(headerName).forEach(headerValue ->
                    log.info("{}< {}: {}", address, headerName, headerValue)));
            val content = response.getContentAsByteArray();
            if (content.length > 0) {
                log.info("{}<", address);
                try {
                    val contentString = new String(content, request.getCharacterEncoding());
                    Stream.of(contentString.split("\r\n|\r|\n")).forEach(line -> log.info("{}< {}", address, line));
                } catch (UnsupportedEncodingException e) {
                    log.info("{}< [{} bytes body]", address, content.length);
                }
            }
        }
    }

    private static ContentCachingRequestWrapper wrapRequest(HttpServletRequest request) {
        if (request instanceof ContentCachingRequestWrapper) {
            return (ContentCachingRequestWrapper) request;
        } else {
            return new ContentCachingRequestWrapper(request);
        }
    }

    private static ContentCachingResponseWrapper wrapResponse(HttpServletResponse response) {
        if (response instanceof ContentCachingResponseWrapper) {
            return (ContentCachingResponseWrapper) response;
        } else {
            return new ContentCachingResponseWrapper(response);
        }
    }
}

标签: springspring-mvcspring-boot

解决方案


推荐阅读