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

如何在RouterFunction执行完成后通过ServerResponse执行逻辑?(doOnNext未生效)

解决方案

你遇到的问题是因为ServerResponse是延迟渲染的,doOnNext仅在Mono<ServerResponse>发射元素时触发,但此时响应还未实际写入客户端,甚至可能因为操作符的冷流特性导致回调未执行。要在RouterFunction执行完成(即响应已发送给客户端)后执行逻辑,正确的实现方式是包装ServerResponse并重写其writeTo方法,在响应写入完成后触发后续逻辑:

public HandlerFilterFunction<ServerResponse, ServerResponse> addMetrics() {
    return (request, next) -> next.handle(request)
            .map(response -> new ServerResponseDecorator(response) {
                @Override
                public Mono<Void> writeTo(ServerWebExchange exchange, Context context) {
                    // 先完成原响应的写入操作,写入完成后执行指标收集
                    return super.writeTo(exchange, context)
                            .doOnSuccess(unused -> meterService.addMetric(this));
                }
            });
}

为什么之前的方案无效?

  • doOnNext是在Mono发射ServerResponse对象时执行,此时响应还未开始写入客户端,甚至如果后续没有订阅这个Mono(比如框架内部的订阅逻辑有差异),doOnNext根本不会触发。
  • 而通过ServerResponseDecorator重写writeTo方法,我们能确保逻辑在响应实际写入完成后执行,这才是真正的"RouterFunction执行完成"的时机。

另外,如果你不需要等待响应写入完成,只是想在RouterFunction处理完请求、生成ServerResponse对象后立即执行逻辑,可以用doOnSuccess替代doOnNext,它会在Mono成功发射元素时可靠触发:

public HandlerFilterFunction<ServerResponse, ServerResponse> addMetrics() {
    return (request, next) -> next.handle(request)
            .doOnSuccess(response -> meterService.addMetric(response));
}

需要注意的是,这种方式的逻辑执行时机是在响应对象生成后、写入客户端前,根据你的实际需求选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:20:51