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)) } }
问题原因
- 请求过滤器的
add()方法特性:生成新Correlation ID时,add()会追加Header条目,而Quarkus默认会将请求头传递到响应中,这已经是第一个X-Correlation-Id; - 响应过滤器重复添加:响应过滤器再次调用
add()追加同一个Header,最终导致重复; 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
相关产品推荐
相关产品推荐

