有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java doOnNext()不会被称为Spring Webflux

我是反应式编程的新手,也是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只订阅最外部的发布者,内部的发布者不会被触发,我已经更新了代码,但仍然无法工作


共 (1) 个答案

  1. # 1 楼答案

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

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

    只需将doOnNext替换为flatMap(并用switchIfEmpty保留对最内部doOnNext的更改),使其成为Spring将订阅的反应链的一部分