【问题标题】:Mapping imperative conditional statements (with exception throwing) to Reactive process将命令式条件语句(带有异常抛出)映射到反应式进程
【发布时间】:2022-01-23 20:34:06
【问题描述】:

我正在努力理解反应式流程。我的理解是,在MonoFlux 中操作数据时,必须保持类型一致性。但是,当该进程中出现问题时,必须抛出类似于异常的东西,这会破坏类型一致性。

目前,我有一个命令式流程来获取验证令牌 ID 并对其进行处理。在两种情况下,它会抛出异常(InvalidTokenException404 响应;ExpiredTokenException410),最后修改并保存帐户,并删除令牌。我想将其转换为反应过程:

public AccountDto verifyAccountByToken (UUID tokenId) {
    VerifyToken vToken = verifyTokenRepository.findByToken(tokenId);
    if (vToken == null) {
        throw new InvalidTokenException();
    }
    if (vToken.isExpired()) {
        verifyTokenRepository.delete(vToken);
        throw new ExpiredTokenException();
    }
    Account account = vToken.getAccount();
    account.addRole(AccountRole.VERIFIED);
    account.deleteRole(AccountRole.UNVERIFIED);
    accountRepository.save(account);
    verifyTokenRepository.delete(vToken);
    return new AccountDto(account);
}

我相信下面的内容对于数据操作过程来说基本上是正确的,但我应该如何处理条件分支? – 我怎么说:做这个如果空? (我想我可以使用.filter() 作为捕获过期案例的一种方式。)如何将其转换为错误类型?

public Mono<AccountDto> verifyAccountByToken (UUID tokenId) {
    return verifyTokenRepository.findByToken(tokenId)
            
            // the bits I can't figure out to deal with Invalid and Expired tokens;
            
            .flatMap(vToken -> {
                verifyTokenRepository.delete(vToken);
                return vToken.getAccount();
            })
            .flatMap(account -> {
                account.addRole(AccountRole.VERIFIED);
                account.deleteRole(AccountRole.UNVERIFIED);
                return accountRepository.save(account);
            })
            .map(account -> new AccountDto(account));
}

【问题讨论】:

    标签: java project-reactor


    【解决方案1】:

    我怎么说:do-this-if-empty?

    有一个操作符:

     .switchIfEmpty(Mono.error(new InvalidTokenException()));
    

    看看下面的cmets:

    public Mono<AccountDto> verifyAccountByToken(UUID tokenId) {
      return verifyTokenRepository.findByToken(tokenId) //Mono<VerifyToken> or Mono<Void>
              .switchIfEmpty(Mono.error(new InvalidTokenException())); //token does not exist, empty Mono is returned, switch to an error signal
              .flatMap(this::validateToken)
              .map(vToken -> vToken.getAccount())
              .flatMap(account -> {
                    //token is valid...
                    account.addRole(AccountRole.VERIFIED);
                    account.deleteRole(AccountRole.UNVERIFIED);
                    return accountRepository.save(account);
                })
              .map(account -> new AccountDto(account));
    }
    
    private Mono<VerifyToken> validateToken(VerifyToken vToken) {
        if (vToken.isExpired()) {
            //Token is expired... delete it and then signal an error
             return verifyTokenRepository.delete(vToken) 
                      .then(Mono.error(new ExpiredTokenException()));
        }
        return Mono.just(vToken);//token is valid...
    }
    

    【讨论】:

    • 谢谢。看起来它会做我想要的(尽管您在解决方案中放弃了从 vTokenaccount 的转换步骤;我可能会将其包含在 validateToken() 中)
    • @Rick 我会在令牌验证后这样做。已编辑。
    • 我将valitadeToken 更改为redeemToken,结合了令牌删除(这也是缺失的),因此(我认为)在那里处理它是有意义的,因为一旦令牌被赎回,我们已经回复了Account(仍需验证)。
    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多