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

纯SpringMVC框架下如何实现请求全信息日志记录?

Logging Full Incoming Request Details in Plain Spring MVC (No Spring Boot)

Great question! When working with plain Spring MVC (without Spring Boot's auto-config magic), you won't get out-of-the-box request logging like you do in Boot—but there are Spring-native solutions you can use, plus flexible custom options if you need more control. Let's break this down:

1. Use Spring's Built-in CommonsRequestLoggingFilter

This is the easiest and most "Spring-native" approach—no extra dependencies needed, just leveraging what's already in the spring-web module.

How to Configure It

You'll need to register this filter explicitly (since there's no Spring Boot auto-config to do it for you). Here's how to set it up with both Java and XML configuration:

Java Configuration

Create a @Configuration class (or add to your existing Spring MVC config) to define the filter bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CommonsRequestLoggingFilter;

@Configuration
public class RequestLoggingConfig {

    @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
        // Enable logging of request details you care about
        loggingFilter.setIncludeClientInfo(true); // Logs client IP, user agent
        loggingFilter.setIncludeQueryString(true); // Logs URI query parameters
        loggingFilter.setIncludePayload(true); // Logs request body
        loggingFilter.setMaxPayloadLength(10000); // Limit payload size to avoid huge logs
        loggingFilter.setIncludeHeaders(false); // Optional: set to true if you need headers too
        return loggingFilter;
    }
}

XML Configuration

If you're using XML-based Spring config, add this to your dispatcher-servlet.xml (or root context):

<bean id="requestLoggingFilter" class="org.springframework.web.filter.CommonsRequestLoggingFilter">
    <property name="includeClientInfo" value="true"/>
    <property name="includeQueryString" value="true"/>
    <property name="includePayload" value="true"/>
    <property name="maxPayloadLength" value="10000"/>
    <property name="includeHeaders" value="false"/>
</bean>

<!-- Map the filter to all incoming requests -->
<filter-mapping>
    <filter-name>requestLoggingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Critical Note: Log Level Setup

This filter logs details at the DEBUG level, so you need to configure your logging framework (Logback, Log4j, etc.) to enable DEBUG logs for the filter class. For example, in Logback:

<logger name="org.springframework.web.filter.CommonsRequestLoggingFilter" level="DEBUG"/>

Why This Works

The filter uses ContentCachingRequestWrapper under the hood, which caches the request body so it can be read for logging without breaking subsequent request processing (since the original input stream can only be read once).

2. Create a Custom Filter (For Full Control)

If you need more flexibility—like custom log formatting, adding extra context, or filtering sensitive data—you can create your own filter by extending OncePerRequestFilter (Spring's base class for filters that run once per request):

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.springframework.util.StreamUtils;
import org.springframework.web.util.ContentCachingRequestWrapper;

public class CustomRequestLoggingFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // Capture request details
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        String clientIp = request.getRemoteAddr();
        // For proxied requests, you might need to get X-Forwarded-For header:
        // String clientIp = request.getHeader("X-Forwarded-For") != null ? request.getHeader("X-Forwarded-For") : request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        
        // Wrap request to cache body for logging
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        filterChain.doFilter(wrappedRequest, response); // Let request proceed first
        
        // Read cached request body
        String requestBody = new String(wrappedRequest.getContentAsByteArray(), StandardCharsets.UTF_8);
        
        // Log with your preferred format/level
        logger.info("Incoming Request - URI: {}, Query: {}, Client IP: {}, User Agent: {}, Body: {}",
                uri, queryString, clientIp, userAgent, requestBody);
    }
}

Then register this filter just like the built-in one (via Java or XML config).

Why enableLoggingRequestDetails Didn't Work

That configuration property is specific to Spring Boot—it's part of Boot's auto-configuration for request logging, which automatically sets up CommonsRequestLoggingFilter when enabled. In plain Spring MVC, there's no auto-config infrastructure to pick up that property, so setting it has no effect.

Final Recommendations

  • Start with CommonsRequestLoggingFilter first—it's simple, maintained by Spring, and covers all your basic needs.
  • Use a custom filter only if you need to tweak the log format, redact sensitive data (like passwords in the request body), or add custom context.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:07:23