英文:
doOnNext() won't get called Spring Webflux
问题
这是我的方法:
@Override
public Mono<RegistrationVerificationResDTO> verifyCustomerAndGenerateToken(Mono<VerifyOtpReqDTO> verifyOtpReqDTO) {
return verifyOtpReqDTO
.flatMap(verifyDTO -> reactiveRedisOperations
.opsForValue()
.get(RedisDictionary.OTP_KEY + verifyDTO.getPhoneNumber())
.filter(otp -> otp.equalsIgnoreCase(verifyDTO.getOtp()))
.switchIfEmpty(Mono.error(ForbiddenException::new))
.then(Mono.just(verifyDTO))) // Continue with verifyDTO
.flatMap(verifyDTO -> customerRepository.findById(verifyDTO.getId())
.switchIfEmpty(Mono.error(() -> new NotFoundException("Customer not found"))))
.flatMap(customer -> {
customer.setVerified(true);
return customerRepository.save(customer)
.thenReturn(customer);
})
.map(customer -> new RegistrationVerificationResDTO()
.setAccessToken("accessToken")
.setRefreshToken("refreshToken")
.setCustomer(customer));
}
更新:
我意识到如果我们在 doOnNext
方法内部创建另一个发布者,因为 Spring 只会订阅最外层的发布者,内部的发布者不会被触发。我已经更新了我的代码,但它仍然不起作用。
英文:
I'm a newbie in reactive programming and also Spring Webflux
I have a method to get some key from Redis and if this key is null or is not equals to the specified string i want to throw an exception but the nested donOnNext method won't get called and customerRepository.save(customer)
get triggered while the exception must be thrown and break the chain. Can someone explain to me how the reactor API behaves in my case?
this is my method:
@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));
}
UPDATE:
I realized if we create another publisher inside the doOnNext method because the spring just subscribes to the most outer publisher the inner one won't get triggered I have updated my code but it still doesn't work.
答案1
得分: 4
我猜您是在说这个“不起作用”,因为您无法观察到已保存的customer
在数据库中,即使在您对第二个(最内层)doOnNext
进行了(正确的)更改后也是如此。
第三个doOnNext
是有问题的:假设customerRepository
是一个响应式存储库,customerRepository.save(customer)
是一个无操作操作,因为(惰性的)Mono
既没有连接到主序列,也没有被订阅。
只需将该doOnNext
替换为 flatMap
(并且也保留您对最内层的doOnNext
进行的更改,使用switchIfEmpty
),以使其成为Spring将订阅的响应式链的一部分。
英文:
I'm guessing you're saying this "doesn't work" because you can't observe the saved customer
in DB, even after the (correct) changes you've made to the second (innermost) doOnNext
?
The third doOnNext
is problematic: customerRepository.save(customer)
is a NO-OP assuming customerRepository
is a reactive repository, because the (lazy) Mono
is neither attached to the main sequence nor subscribed to.
Simply replace that doOnNext
with flatMap
(and keep your changes to the innermost doOnNext with switchIfEmpty
as well) to make it part of the reactive chain that Spring will subscribe to.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论