You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ContentCachingRequestWrapper无法获取请求体的原因排查

请求体为空的原因及修复方案

问题根源

你的代码存在两个关键错误,导致无法获取请求体:

  • 误用原始请求对象:在logRequest方法中,你调用了request.getContentAsByteArray(),但原始的HttpServletRequest没有请求体缓存能力,必须使用ContentCachingRequestWrapper实例来读取缓存的请求体。
  • 日志记录时机错误:你在执行filterChain.doFilter()之前就调用了logRequest,此时后续的Controller还未读取请求体,ContentCachingRequestWrapper还没完成请求体的缓存操作。

修正后的代码

@Component
public class RequestResponseLoggingFilter extends OncePerRequestFilter {

    private final Logger logger = LoggerFactory.getLogger(RequestResponseLoggingFilter.class);

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
    
        // 先让请求流转到后续处理器,完成请求体的读取和缓存
        filterChain.doFilter(wrappedRequest, wrappedResponse);
        
        // 此时再记录请求和响应
        logRequest(wrappedRequest);
        logResponse(wrappedResponse);
        
        wrappedResponse.copyBodyToResponse();
    }

    private void logRequest(ContentCachingRequestWrapper wrappedRequest) {
        logger.info("Request: {} {}", wrappedRequest.getMethod(), wrappedRequest.getRequestURI());

        byte[] requestBody = wrappedRequest.getContentAsByteArray();
        if (requestBody.length > 0) {
            String requestBodyString = new String(requestBody, StandardCharsets.UTF_8);
            logger.info("Request Body: {}", requestBodyString);
        }
    }

    private void logResponse(ContentCachingResponseWrapper wrappedResponse) {
        logger.info("Response: {}", wrappedResponse.getStatus());
     
        byte[] responseBody = wrappedResponse.getContentAsByteArray();
        if (responseBody.length > 0) {
            String responseBodyString = new String(responseBody, StandardCharsets.UTF_8);
            logger.info("Response Body: {}", responseBodyString);
        }
    }
}

关键改动说明

  1. 调整日志记录顺序:将logRequest和logResponse的调用移到filterChain.doFilter()之后,确保请求体已经被后续处理器读取并缓存到wrappedRequest中。
  2. 使用wrappedRequest读取请求体:在logRequest中替换为wrappedRequest.getContentAsByteArray(),正确读取缓存的请求体内容。

内容的提问来源于stack exchange,提问作者Kevin Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 00:22:32