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

