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 之间没有区别,你能用这句话澄清你的意思吗? 在doOnNext
和 flatMap
内处理 Mono/Flux 之间存在巨大差异:Spring 确实订阅了控制器返回的外部 Mono 或 Flux,但该订阅仅传播发布者是链中的链接。在 doOnNext
中生成 Publisher 不会使其成为链接链,而从 flatMap
返回 Publisher 则可以。
我在问题描述中更新了我的代码,您可以查看一下吗?以上是关于doOnNext() 不会被称为 Spring Webflux的主要内容,如果未能解决你的问题,请参考以下文章
Shiro 不会重定向到未经授权的Url w/invalid login - Shiro with Spring and Tiles