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

SpringCloud Gateway过滤器设置Reactor3 Context下游Controller无法获取求助

问题根因
  • Reactor Context的作用域限制:Reactor的Context是单进程内响应式流订阅链路专属的上下文,仅在同一条响应式流的上下游传播。你当前场景中Spring Cloud Gateway和下游业务服务是两个独立运行的进程,网关只是负责转发HTTP请求,两个服务的响应式流完全独立,Context不可能跨进程传递。
  • Context设置位置有误:Reactor的Context是从订阅端向上游传播的,你将subscriberContext写在chain.filter(exchange)之后,执行过滤器链时还未写入Context,就算是同服务内的场景也无法读到值。
解决方案

场景1:网关转发到独立的下游服务

直接通过自定义请求头传递参数,网关将参数写入请求头后转发,下游服务读取请求头即可:

网关过滤器代码

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    // 修改请求,添加自定义头携带参数
    ServerHttpRequest newRequest = exchange.getRequest().mutate()
            .header("x-custom-key", "hello gate")
            .build();
    return chain.filter(exchange.mutate().request(newRequest).build());
}

下游Controller代码

@ResponseBody
@RequestMapping("/test")
public Mono<String> test(@RequestHeader("x-custom-key") String key) {
    return Mono.just(key);
}

如果参数敏感,可在下游服务的全局拦截器中读完请求头后移除,避免返回给客户端时泄露。

场景2:网关本身提供本地接口(未转发到其他服务)

如果是网关服务内部的Controller需要读取Context,要修正Context的API写法和位置:

注意:Reactor 3.4+版本已废弃subscriberContext,统一使用contextWrite写入Context,deferContextual读取Context。

网关过滤器代码

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    // contextWrite写在过滤器链执行前,确保能传播到下游流
    return chain.filter(exchange)
            .contextWrite(ctx -> ctx.put("key", "hello gate"));
}

网关本地Controller代码

@ResponseBody
@RequestMapping("/local-test")
public Mono<String> localTest() {
    return Mono.deferContextual(ctx -> Mono.just(ctx.get("key")));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 16:45:03