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

如何在Spring MVC中记录HTTP请求头及其他相关数据?

嗨,我来给你几个实用的方案,帮你在Spring MVC的GET请求日志里带上HTTP请求头和其他请求数据~

方案1:用HandlerInterceptor全局统一处理(推荐)

这个方法不用修改每个控制器方法,能全局给所有请求的日志自动加上请求头信息,非常省心。

步骤1:自定义请求日志拦截器

创建一个实现HandlerInterceptor的类,在请求进入控制器前把需要的请求头/请求数据放到**MDC(映射诊断上下文)**里——MDC是Logback的特性,能让你在日志模板里引用这些变量:

public class RequestLoggingInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 把需要的请求信息存入MDC,按需添加(注意敏感信息要脱敏!比如Authorization只存前几位)
        MDC.put("userAgent", request.getHeader("User-Agent"));
        MDC.put("requestUri", request.getRequestURI());
        MDC.put("remoteIp", request.getRemoteAddr());
        // 如果要记录其他请求头,比如Accept-Language,直接用request.getHeader("Accept-Language")
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 必须清除MDC!因为Web容器的线程是复用的,不清除会导致后续请求拿到旧数据
        MDC.clear();
    }
}

步骤2:把拦截器注册到Spring MVC

用Java配置把上面的拦截器加进去:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RequestLoggingInterceptor());
    }
}

步骤3:修改Logback的日志模板

在你的<pattern>里加入MDC变量,用%X{变量名}的格式:

<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - IP:%X{remoteIp}, UA:%X{userAgent}, URI:%X{requestUri} - %msg%n</pattern>

这样你原来的LOG.info("user successfully validated")就会自动带上这些请求信息,输出类似:

14:35:22.123 [http-nio-8080-exec-1] INFO  com.example.BookmarkController - IP:127.0.0.1, UA:Mozilla/5.0..., URI:/users/john/bookmarks - user successfully validated
方案2:在控制器方法中直接获取并记录(适合局部需求)

如果只需要在特定的GET方法里记录请求头,不想全局处理,可以直接在方法参数里用@RequestHeader或者HttpServletRequest拿到数据,然后写到日志里:

@RequestMapping(method = RequestMethod.GET)
Collection<Bookmark> readBookmarks(
        @PathVariable String userId,
        @RequestHeader("User-Agent") String userAgent,
        HttpServletRequest request
) {
    this.validateUser(userId);
    // 直接把需要的信息拼到日志里
    LOG.info("user successfully validated | IP: {}, UA: {}, URI: {}",
            request.getRemoteAddr(), userAgent, request.getRequestURI());
    return this.bookmarkRepository.findByAccountUsername(userId);
}

这个方法灵活,但缺点是每个需要的方法都要加参数和日志代码,重复劳动比较多。

方案3:用Spring自带的CommonsRequestLoggingFilter

Spring提供了现成的请求日志过滤器,配置一下就能自动记录请求头、客户端信息等,适合快速实现全局请求日志:

步骤1:配置过滤器

@Configuration
public class LoggingFilterConfig {
    @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
        filter.setIncludeHeaders(true); // 开启请求头记录
        filter.setIncludeClientInfo(true); // 记录客户端IP、主机名
        filter.setIncludeQueryString(true); // 记录URL查询参数
        filter.setIncludePayload(false); // GET请求一般没有请求体,设为false
        filter.setBeforeMessagePrefix("[REQUEST] "); // 日志前缀,方便识别
        return filter;
    }
}

步骤2:调整Logback日志级别

这个过滤器默认用DEBUG级别输出日志,所以需要在Logback里把它的日志级别打开:

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

之后它会自动打印类似这样的日志:

14:40:11.456 [http-nio-8080-exec-2] DEBUG o.s.w.f.CommonsRequestLoggingFilter - [REQUEST] Before request [GET /users/john/bookmarks, client=127.0.0.1, headers=[User-Agent:"Mozilla/5.0...", Accept:"application/json"]]

不过这个方案的日志格式比较固定,如果需要自定义格式,不如方案1灵活。

注意事项

  • 敏感信息脱敏:比如Authorization头里的token,不要直接完整记录,只存前几位或者用星号替换中间部分,避免泄露敏感数据。
  • MDC清理:方案1里一定要在afterCompletion里清除MDC,否则线程复用会导致日志混乱。
  • 性能考虑:如果是高并发场景,全局日志要注意不要记录太多冗余数据,避免影响性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:14:59