ContentCachingResponseWrapper Produces Empty Response

前端 未结 3 882
傲寒
傲寒 2020-11-29 03:54

I\'m trying to implement filter for logging requests and responses in Spring MVC application. I use the following code:

@Component
public class          


        
3条回答
  •  心在旅途
    2020-11-29 04:22

    The pattern I like to use is to split this into 2 filters, one for extracting the raw body and another one to do the logging - feels a more SRP.

    @Slf4j        // lombok logging
    @Component    // spring loads filter into it's filter chain
    @Order(1)     // Best if this goes first (or early in filter chain)
    public class CachingBodyFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
            ContentCachingRequestWrapper reqWrapper = new ContentCachingRequestWrapper((HttpServletRequest) req);
            ContentCachingResponseWrapper resWrapper = new ContentCachingResponseWrapper((HttpServletResponse) res);
            try {
                chain.doFilter(reqWrapper, resWrapper);
                resWrapper.copyBodyToResponse();  // Necessary (see answer by StasKolodyuk above)
            } catch (IOException | ServletException e) {
                log.error("Error extracting body", e);
            }
        }
    
    }
    

    And then we create another filter to do the logging part.

    @Slf4j
    @Component
    @Order(2)     // This needs to come after `CachingBodyFilter`
    public class PayloadLogFilter implements Filter {
    
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(req, res);
    
            if (req instanceof ContentCachingRequestWrapper) {
                ContentCachingRequestWrapper reqWrapper = (ContentCachingRequestWrapper) req;
                String payload = new String (reqWrapper.getContentAsByteArray(), "utf-8");
                log.debug("Request [ {} ] has payload [ {} ]", reqWrapper.getRequestURI(), payload);
            }
        }
    
    }
    

    A nice advantage of splitting these up is that other classes (e.g. a Spring AOP interceptor or a Spring controller) can also access / use the HTTP body.

提交回复
热议问题