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

如何在Java Spring Boot API请求中添加UUID格式的Correlation-Id头部

在Spring Boot(Swagger生成代码)中自动添加Correlation-Id请求头并关联日志

1. 用ThreadLocal实现Correlation-Id上下文共享

先写一个工具类,用ThreadLocal存储Correlation-Id,保证请求链路内的线程安全,同时集成你已有的UUID生成逻辑:

public class CorrelationIdHolder {
    private static final ThreadLocal<String> CORRELATION_ID = new ThreadLocal<>();

    public static String getCorrelationId() {
        String id = CORRELATION_ID.get();
        if (id == null) {
            id = generateUniqueCorrelationId();
            setCorrelationId(id);
        }
        return id;
    }

    public static void setCorrelationId(String correlationId) {
        CORRELATION_ID.set(correlationId);
    }

    public static void clear() {
        CORRELATION_ID.remove();
    }

    private static String generateUniqueCorrelationId() {
        return UUID.randomUUID().toString();
    }
}

2. 编写拦截器自动注入/处理请求头

实现Spring的HandlerInterceptor,在请求进入时自动生成(或复用传入的)Correlation-Id,同时写入响应头方便客户端追踪,请求结束后清理上下文:

@Component
public class CorrelationIdInterceptor implements HandlerInterceptor {
    private static final String CORRELATION_ID_HEADER = "Correlation-Id";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 优先取请求头里的ID,没有则自动生成
        String correlationId = request.getHeader(CORRELATION_ID_HEADER);
        if (correlationId == null || correlationId.isBlank()) {
            correlationId = CorrelationIdHolder.generateUniqueCorrelationId();
        }
        CorrelationIdHolder.setCorrelationId(correlationId);
        // 把ID写入响应头,让客户端能拿到
        response.setHeader(CORRELATION_ID_HEADER, correlationId);
        // 放入MDC供日志使用
        MDC.put("correlationId", correlationId);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 必须清理,避免线程复用导致ID混乱或内存泄漏
        CorrelationIdHolder.clear();
        MDC.remove("correlationId");
    }
}

然后注册这个拦截器,让它对所有API生效:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    private final CorrelationIdInterceptor correlationIdInterceptor;

    public WebConfig(CorrelationIdInterceptor correlationIdInterceptor) {
        this.correlationIdInterceptor = correlationIdInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(correlationIdInterceptor)
                .addPathPatterns("/**");
    }
}

3. 让Swagger生成的API自动关联Correlation-Id

在你的Swagger YAML中定义全局请求参数,这样生成的接口文档会包含该字段,Swagger UI调用时也会自动提示(或携带默认UUID):

openapi: 3.0.3
info:
  title: 你的API名称
  version: 1.0.0
servers:
  - url: http://localhost:8080

components:
  parameters:
    CorrelationId:
      name: Correlation-Id
      in: header
      required: false # 设为非必填,拦截器会自动兜底生成
      schema:
        type: string
        format: uuid
        example: "550e8400-e29b-41d4-a716-446655440000"

# 所有接口引用这个全局参数
paths:
  /your-api-path:
    get:
      parameters:
        - $ref: '#/components/parameters/CorrelationId'
      responses:
        '200':
          description: 成功响应

如果需要所有接口自动关联,也可以通过OpenAPI Generator的配置参数(比如globalParameters)批量添加,不需要逐个接口写引用。

4. 日志中自动带上Correlation-Id

如果你用SLF4J + Logback,修改日志配置文件(比如logback-spring.xml),在格式中加入%X{correlationId}:

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %X{correlationId} - %msg%n</pattern>
    </encoder>
</appender>

这样所有日志都会自动带上当前请求的Correlation-Id,方便排查问题时追踪完整链路。

额外提示

  • 如果你的服务需要调用其他微服务,可以给Feign添加RequestInterceptor,把Correlation-Id传递过去,实现全链路追踪。
  • 务必保证ThreadLocal和MDC在请求结束后清理,否则会出现线程复用导致的ID错乱或内存泄漏问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:05:32