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

Spring Boot 3.4.2升级后ServerHttpRequest#getURI()行为改变,如何恢复旧逻辑获取内部请求路径?

Spring Boot 3.4.2升级后ServerHttpRequest#getURI()行为改变,如何恢复旧逻辑获取内部请求路径?

看起来这个问题是因为Spring Boot 3.4.x(基于Spring Framework 6.2)调整了Forwarded Headers的默认处理逻辑,导致ServerHttpRequest默认使用了Kong传递的外部请求信息(来自X-Forwarded-*系列Header),而不再显示应用实际接收到的内部路径。下面给你两种可行的解决方案:

方案1:直接获取应用实际接收的内部路径(推荐)

不管全局的Forwarded Headers配置如何,你都可以通过Spring WebFlux内置的HandlerMapping属性,直接拿到Kong转发后实际到达应用的内部路径。

只需要在你的接口方法中注入ServerWebExchange,然后读取对应的属性即可:

@PostMapping(value = "**", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<ResponseEntity<byte[]>> genericPost(
        @RequestBody byte[] body,
        @RequestHeader HttpHeaders headers,
        ServerHttpRequest request,
        ServerWebExchange exchange) { // 新增ServerWebExchange参数

    // 获取应用内部实际接收的路径,这里会输出/,和3.3.8版本的结果一致
    String internalPath = exchange.getRequiredAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
    log.trace("> internal path {}", internalPath);

    // 保留你原有的日志逻辑
    log.trace("> getURI {}", request.getURI());
    log.trace("> getPath {}", request.getPath());
    // ... 你的后续业务逻辑
}

这个方法的好处是不需要修改全局配置,直接拿到HandlerMapping匹配到的真实路径,完全不受Forwarded Headers解析逻辑的影响,非常稳妥。

方案2:调整Forwarded Headers的全局处理逻辑

如果你希望让ServerHttpRequest的getPath()/getURI()直接回到3.3.8版本的行为(默认显示内部路径),可以通过配置修改Spring对转发头的处理策略:

方式A:忽略X-Forwarded-Path Header

Kong会传递X-Forwarded-Path Header,Spring 6.2默认会把这个路径合并到请求URI中。我们可以让Spring忽略这个Header,只处理其他必要的转发头:

如果你的应用使用Netty(WebFlux默认容器),可以自定义ForwardedHeaderTransformer Bean:

@Configuration
public class WebFluxForwardedConfig {

    @Bean
    public ForwardedHeaderTransformer forwardedHeaderTransformer() {
        ForwardedHeaderTransformer transformer = new ForwardedHeaderTransformer();
        // 告诉Spring不要解析X-Forwarded-Path Header
        transformer.setRemoveOnlyHeaders(Set.of("X-Forwarded-Path"));
        return transformer;
    }
}

如果使用Tomcat作为Web服务器,直接在配置文件中添加:

server:
  forward-headers-strategy: framework
  tomcat:
    remoteip:
      ignored-headers: X-Forwarded-Path

方式B:完全禁用Forwarded Headers解析

如果你的业务不需要通过ServerHttpRequest获取外部请求的host、port等信息,可以直接全局禁用转发头解析:

server:
  forward-headers-strategy: none

这样ServerHttpRequest的getPath()就会直接显示应用实际接收的内部路径,但代价是你无法再通过它获取外部请求的原始信息了。

为什么会出现这个变化?

Spring Boot 3.4.x基于Spring Framework 6.2,这个版本对ForwardedHeaderTransformer的逻辑做了升级,默认开始解析X-Forwarded-Path Header,并将其合并到ServerHttpRequest的URI/Path信息中。而在Spring Framework 6.1(对应Spring Boot 3.3.x)中,X-Forwarded-Path默认不会被解析到请求路径中,所以当时显示的是应用实际接收的路径。

备注:内容来源于stack exchange,提问作者Jairton Junior

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:18:02