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

Quarkus中Rest请求响应自定义Header重复问题求助

解决Quarkus中Rest请求-响应自定义Header重复问题

在使用Quarkus时,自定义的X-Correlation-IdHeader总是重复出现,原过滤器代码如下:

class Filters(var log: Logger) {

    companion object {
        private val CORRELATION_ID_HEADER_NAME = "X-Correlation-Id";
        private val CORRELATION_ID_LOG_VAR_NAME = "correlationId";
    }

    @ServerRequestFilter(preMatching = true)
    fun preMatchingFilter(requestContext: ContainerRequestContext) {
        var corellationId = requestContext.getHeaderString(CORRELATION_ID_HEADER_NAME)
        corellationId ?: run {
            corellationId = UUID.randomUUID().toString()
            requestContext.headers.add(CORRELATION_ID_HEADER_NAME, corellationId)
        }
        MDC.put(CORRELATION_ID_LOG_VAR_NAME, corellationId)
        log.info(MDC.get(CORRELATION_ID_LOG_VAR_NAME))
    }

    @ServerResponseFilter
    fun responseFilter(responseContext: ContainerResponseContext) {
        var corellationId = MDC.get(CORRELATION_ID_LOG_VAR_NAME)
        corellationId ?: run {
            corellationId = UUID.randomUUID().toString()
            responseContext.headers.add(CORRELATION_ID_HEADER_NAME, corellationId)
        }.also { MDC.put(CORRELATION_ID_LOG_VAR_NAME, corellationId) }
        log.info(MDC.get(CORRELATION_ID_LOG_VAR_NAME))
    }
}

问题原因

  1. 请求过滤器的add()方法特性:生成新Correlation ID时,add()会追加Header条目,而Quarkus默认会将请求头传递到响应中,这已经是第一个X-Correlation-Id;
  2. 响应过滤器重复添加:响应过滤器再次调用add()追加同一个Header,最终导致重复;
  3. add()方法逻辑:该方法不会覆盖已存在的Header,而是新增值,即使Header名称相同。

解决方案

  • 请求过滤器用set()替代add(),确保请求中只有一个X-Correlation-Id;
  • 响应过滤器直接复用请求上下文的Correlation ID,无需重复生成,若需设置响应Header,同样用set()避免追加;
  • 从请求上下文获取ID比依赖MDC更可靠,避免异步场景下的MDC上下文丢失问题。

修改后的代码如下:

class Filters(var log: Logger) {

    companion object {
        private val CORRELATION_ID_HEADER_NAME = "X-Correlation-Id";
        private val CORRELATION_ID_LOG_VAR_NAME = "correlationId";
    }

    @ServerRequestFilter(preMatching = true)
    fun preMatchingFilter(requestContext: ContainerRequestContext) {
        var correlationId = requestContext.getHeaderString(CORRELATION_ID_HEADER_NAME)
        correlationId ?: run {
            correlationId = UUID.randomUUID().toString()
            // 使用set方法替代add,确保Header唯一
            requestContext.headers.set(CORRELATION_ID_HEADER_NAME, correlationId)
        }
        MDC.put(CORRELATION_ID_LOG_VAR_NAME, correlationId)
        log.info(correlationId)
    }

    @ServerResponseFilter
    fun responseFilter(responseContext: ContainerResponseContext, requestContext: ContainerRequestContext) {
        // 直接从请求上下文获取已有的Correlation ID
        var correlationId = requestContext.getHeaderString(CORRELATION_ID_HEADER_NAME)
        correlationId ?: run {
            correlationId = UUID.randomUUID().toString()
        }
        // 用set方法确保响应中只有一个该Header
        responseContext.headers.set(CORRELATION_ID_HEADER_NAME, correlationId)
        MDC.put(CORRELATION_ID_LOG_VAR_NAME, correlationId)
        log.info(correlationId)
    }
}

额外说明

  • set()方法会替换Header的所有现有值,确保同一个Header仅存在一个条目;
  • 若业务场景允许,可直接去掉响应过滤器中的Header设置,因为Quarkus默认会将请求头传递到响应中,只需确保请求中已正确设置即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 15:54:14