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

如何在Controller中访问Reactor Context?WebFilter填充场景解析

在WebFilter中设置Reactor Context后,如何在Controller中访问

你的核心误解在于对Reactor Context传递方向和Spring WebFlux请求链的结合逻辑理解有误,下面详细解释并给出实现方案:

1. Reactor Context的核心传递规则

Reactor Context是绑定在订阅关系上的,传递方向是从订阅者(下游)向上游传递。当你调用contextWrite修改Context时,所有位于这个操作上游的Reactor操作,都能访问到修改后的Context。

2. Spring WebFlux请求链中的Context传递逻辑

在WebFilter中,chain.filter(exchange)代表的是后续的请求处理链(包含Controller的业务逻辑)。如果你对chain.filter(exchange)返回的Mono调用contextWrite,相当于给整个后续处理链的订阅路径注入了Context——当Controller中的Mono/Flux被订阅时,订阅请求会向上传递,经过这个Context修改步骤,最终Controller能拿到对应的Context值。

3. 代码实现示例

WebFilter中设置Context

@Component
public class ContextInjectFilter implements WebFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 给后续的Controller处理链注入Context
        return chain.filter(exchange)
                .contextWrite(ctx -> ctx.put("REQUEST_TRACE_ID", "abc-123-xyz"));
    }
}

Controller中访问Context

@RestController
@RequestMapping("/demo")
public class ContextAccessController {

    @GetMapping("/trace")
    public Mono<String> getTraceId() {
        // 使用deferContextual延迟获取Context(必须在订阅阶段执行)
        return Mono.deferContextual(contextView -> {
            String traceId = contextView.get("REQUEST_TRACE_ID");
            return Mono.just("当前请求Trace ID:" + traceId);
        });
    }
}

4. 关键注意事项

  • 必须使用deferContextual或transformDeferredContextual来访问Context:Context是在订阅阶段才确定的,这两个方法会延迟到订阅时执行逻辑,确保能拿到正确的Context。
  • 不要在WebFilter的前置逻辑流上调用contextWrite:比如如果写Mono.just(exchange).contextWrite(...).then(chain.filter(exchange)),这样设置的Context不会传递到Controller,因为chain.filter(exchange)是独立的流。

参考文档

  • Spring WebFlux官方文档:关于Reactor Context在Web请求处理中的集成说明,解释了Filter与Controller之间的Context传递机制。
  • Reactor官方文档:详细说明Context的传递规则、contextWrite和deferContextual的用法与适用场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:25:16