ServerWebExchangeContextFilter 应用案例说明
ServerWebExchangeContextFilter
是一个 Spring WebFlux 过滤器,它的主要作用是将当前的 ServerWebExchange
实例放入到 Reactor 的 Context
中,这样就可以在不需要显式传递 ServerWebExchange
的情况下,让参与请求处理的组件能够访问到它。
业务场景:
这个过滤器特别有用于以下场景:
- 跨组件共享请求上下文:在响应式编程模型中,当需要在不同的处理器或过滤器之间共享
ServerWebExchange
,但又不想通过方法参数显式传递时。 - 简化组件间的数据传递:允许组件直接从 Reactor
Context
中获取ServerWebExchange
,从而简化了代码。 - 访问请求和响应对象:在需要对请求或响应进行操作,但又不希望直接依赖于
ServerWebExchange
对象的组件中。
关键处理代码:
以下是 ServerWebExchangeContextFilter
的关键实现:
-
定义上下文属性名:
public static final String EXCHANGE_CONTEXT_ATTRIBUTE = ServerWebExchangeContextFilter.class.getName() + ".EXCHANGE_CONTEXT";
这是
ServerWebExchange
在 ReactorContext
中的键名。 -
过滤方法实现:
@Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { return chain.filter(exchange).contextWrite(context -> context.put(EXCHANGE_CONTEXT_ATTRIBUTE, exchange)); }
在
filter
方法中,通过chain.filter(exchange)
继续过滤链的处理,并通过contextWrite
操作符将ServerWebExchange
对象放入到 ReactorContext
中。 -
获取
ServerWebExchange
的静态方法:public static Optional<ServerWebExchange> getExchange(ContextView contextView) { return contextView.getOrEmpty(EXCHANGE_CONTEXT_ATTRIBUTE); }
这个方法允许从 Reactor
ContextView
中获取ServerWebExchange
对象。
目的:
ServerWebExchangeContextFilter
使得在响应式流中访问当前的 HTTP 请求和响应上下文变得更加方便。- 它利用了 Reactor 的
Context
特性,为请求处理链中的各个环节提供了一个共享的数据空间。
使用示例:
在需要访问 ServerWebExchange
的地方,可以这样使用:
import reactor.core.publisher.Mono;
import org.springframework.web.server.ServerWebExchange;
public class SomeHandler {
public Mono<Void> handleRequest(ServerWebExchange exchange) {
return exchange.getPrincipal()
.map(Mono::just)
.defaultIfEmpty(Mono.empty())
.flatMap(principal -> {
// 从 Reactor Context 中获取 ServerWebExchange
return ServerWebExchangeContextFilter.getExchange(exchange.getContext())
.map(Mono::just)
.defaultIfEmpty(Mono.error(new IllegalStateException("Exchange not found in context")));
})
// 其他业务逻辑处理...
.then();
}
}
请注意,上述代码是一个示例,实际的实现可能会根据你的具体需求和项目结构进行调整。
转载自:https://juejin.cn/post/7380637950381539366