事实证明这可以使用提供的来实现装饰者: ServerWebExchangeDecorator
, ServerHttpRequestDecorator
and ServerHttpResponseDecorator
, 分别。
这是一个示例请求装饰器,它累积了DataBuffer
请求的默认订阅者读取的内容:
@Slf4j
public class CachingServerHttpRequestDecorator extends ServerHttpRequestDecorator {
@Getter
private final OffsetDateTime timestamp = OffsetDateTime.now();
private final StringBuilder cachedBody = new StringBuilder();
CachingServerHttpRequestDecorator(ServerHttpRequest delegate) {
super(delegate);
}
@Override
public Flux<DataBuffer> getBody() {
return super.getBody().doOnNext(this::cache);
}
@SneakyThrows
private void cache(DataBuffer buffer) {
cachedBody.append(UTF_8.decode(buffer.asByteBuffer())
.toString());
}
public String getCachedBody() {
return cachedBody.toString();
}
只要确保,当你装饰ServerWebExchange
通过了WebFilter
,你还覆盖getRequest()
也返回请求装饰器:
public final class PartnerServerWebExchangeDecorator extends ServerWebExchangeDecorator {
private final ServerHttpRequestDecorator requestDecorator;
private final ServerHttpResponseDecorator responseDecorator;
public PartnerServerWebExchangeDecorator(ServerWebExchange delegate) {
super(delegate);
this.requestDecorator = new PartnerServerHttpRequestDecorator(delegate.getRequest());
this.responseDecorator = new PartnerServerHttpResponseDecorator(delegate.getResponse());
}
@Override
public ServerHttpRequest getRequest() {
return requestDecorator;
}
@Override
public ServerHttpResponse getResponse() {
return responseDecorator;
}
}
在过滤器上:
@Component
public class TracingFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return chain.filter(new PartnerServerWebExchangeDecorator(exchange));
}
}
可以这样使用(注意静态导入的函数):
@Bean
public HttpHandler myRoute(MyHandler handler) {
final RouterFunction<ServerResponse> routerFunction =
route(POST("/myResource"), handler::persistNotification);
return webHandler(toWebHandler(routerFunction))
.filter(new TracingFilter())
.build();
}