doOnNext() 不会被称为 Spring Webflux

Posted

技术标签:

【中文标题】doOnNext() 不会被称为 Spring Webflux【英文标题】:doOnNext() won't get called Spring Webflux 【发布时间】:2020-06-16 06:18:27 【问题描述】:

我是响应式编程和 Spring Webflux 的新手 我有一个从 Redis 获取某个键的方法,如果该键为 null 或不等于指定的字符串,我想抛出异常,但不会调用嵌套的 donOnNext 方法,并且在异常必须触发时customerRepository.save(customer) 会被触发被抛出并打破链条。有人可以向我解释一下在我的情况下反应器 API 的行为方式吗?

这是我的方法:

@Override
public Mono<RegistrationVerificationResDTO> verifyCustomerAndGenerateToken(Mono<VerifyOtpReqDTO> verifyOtpReqDTO) 
    return verifyOtpReqDTO
            .doOnNext(verifyDTO -> reactiveRedisOperations
                    .opsForValue()
                    .get(RedisDictionary.OTP_KEY + verifyDTO.getPhoneNumber())
                    .filter(otp -> otp.equalsIgnoreCase(verifyDTO.getOtp()))
                    .switchIfEmpty(Mono.error(ForbiddenException::new)))
            .map(verifyDTO -> customerRepository.findById(verifyDTO.getId())
                    .orElseThrow(() -> new NotFoundException("Customer not found")))
            .doOnNext(customer -> 
                customer.setVerified(true);
                customerRepository.save(customer);
            )
            .map(customer -> new RegistrationVerificationResDTO().setAccessToken("accessToken")
                    .setRefreshToken("refreshToken")
                    .setCustomer(customer));

更新: 我意识到如果我们在 doOnNext 方法中创建另一个发布者,因为 spring 只是订阅了最外部的发布者,内部的发布者不会被触发我已经更新了我的代码,但它仍然不起作用。

【问题讨论】:

你在某个时候打电话给subscribe () @daniu Spring 自动调用它 在返回的Mono?怎么样? @daniu ***.com/questions/50795071/… doOnNext 只是回调,说明当上面的 Mono 成功完成时要做什么,.. 通常我们记录一些东西或更新一些值,但它不用于返回一些东西或抛出异常.. 所以总结一下, 你在 doOnNext 中的异常被吞掉 如果你想抛出异常然后做不同的事情,即在这里检查:***.com/questions/53595420/… 【参考方案1】:

我猜你说这个“不起作用”是因为你无法观察到数据库中保存的customer,即使在你对第二个(最里面的)@ 进行了(正确)更改之后987654322@?

第三个doOnNext 是有问题的:customerRepository.save(customer) 是一个 NO-OP,假设 customerRepository 是一个反应式存储库,因为(懒惰的)Mono 既没有附加到主序列也没有订阅。

只需将 doOnNext 替换为 flatMap(并将对最里面的 doOnNext 的更改也保留为 switchIfEmpty),使其成为 Spring 将订阅的响应链的一部分。

【讨论】:

不,您的猜测不正确,问题是客户保存在数据库中,但我的期望是在此之前抛出异常,请在我的问题中考虑“嵌套”一词。但是感谢您在第三段中的建议,我会尝试一下,我会及时通知您。我的另一个问题是关于您提到的这句话:使其成为 spring 将订阅的响应链的一部分。根据我的知识,spring 会自动订阅链,doonnext 或 flatmap 之间没有区别,你能用这句话澄清你的意思吗? doOnNextflatMap 内处理 Mono/Flux 之间存在巨大差异:Spring 确实订阅了控制器返回的外部 Mono 或 Flux,但该订阅仅传播发布者是链中的链接。在 doOnNext 中生成 Publisher 不会使其成为链接链,而从 flatMap 返回 Publisher 则可以。 我在问题描述中更新了我的代码,您可以查看一下吗?

以上是关于doOnNext() 不会被称为 Spring Webflux的主要内容,如果未能解决你的问题,请参考以下文章

RxJava操作符doOnNext

RXJAVA-doOnNext

RXJAVA-doOnNext

RXJAVA-doOnNext

RXJAVA-doOnNext

Shiro 不会重定向到未经授权的Url w/invalid login - Shiro with Spring and Tiles