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

Spring Webflux结合Spring MVC使用doOnEach时抛出空值异常问题

Why does using doOnEach with Spring WebFlux cause a null attribute exception?

这问题我之前也碰到过,核心原因其实是**doOnEach和map处理信号的逻辑完全不一样**,咱们一步步拆解:

1. doOnEach会处理所有类型的Signal信号

Reactor中的doOnEach方法接收的是Signal<T>类型的参数,这个Signal涵盖了流的三种核心事件:

  • onNext:携带正常的业务数据(也就是你收集到的List<User>)
  • onError:流发生错误时的信号
  • onComplete:流正常结束时的信号

当你的collectList()执行完成后,会先发送一个onNext信号(带着收集好的用户列表),紧接着会发送一个onComplete信号表示流结束。而当Signal是onComplete类型时,调用signal.get()会返回null——这就是你触发ConcurrentModel非空断言的直接原因。

2. 为什么map就能正常运行?

map方法只会响应onNext信号,只有当流中有正常数据传递时才会执行逻辑,完全不会处理onComplete或onError信号。所以在map里调用model.addAttribute("users", users)时,users一定是有效的非空列表,自然不会触发异常。

3. 如果一定要用doOnEach,该怎么修复?

你需要先判断当前Signal的类型,只在onNext时处理属性添加:

@GetMapping 
public Mono<String> list(final Model model) { 
    return this.userRepository.findAll() 
        .collectList() 
        .doOnEach(signal -> {
            // 只处理正常的业务数据信号
            if (signal.isOnNext()) {
                model.addAttribute("users", signal.get());
            }
        }) 
        .map(u -> "users/list"); 
}

额外提醒:关于副作用处理的最佳实践

你提到“在map中处理副作用并非最佳实践”,这点其实要结合Spring WebFlux的场景来看:Model是请求作用域的对象,在map中修改它是完全安全的,而且符合Spring的设计预期。反而doOnEach更适合做日志、监控这类和业务逻辑无关的副作用操作,不建议用来修改请求上下文相关的状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:25:01