Rest Spring webflux:webClient put调用

Rest Spring webflux:webClient put调用,rest,spring-boot,reactive-programming,spring-webflux,Rest,Spring Boot,Reactive Programming,Spring Webflux,我有一个客户服务和一个产品服务。当用户请求购买产品时(我没有包括用户服务,它工作正常,没有问题),产品服务会检查帐户中是否有足够的资金,并更新余额。以下代码可以正常工作: @GetMapping("/account/{userId}/product/{productId}") public Mono<ResponseEntity<Product>> checkAccount(@PathVariable("userId") int userId,@PathVaria

我有一个客户服务和一个产品服务。当用户请求购买产品时(我没有包括用户服务,它工作正常,没有问题),产品服务会检查帐户中是否有足够的资金,并更新余额。以下代码可以正常工作:

@GetMapping("/account/{userId}/product/{productId}")
    public Mono<ResponseEntity<Product>> checkAccount(@PathVariable("userId") int userId,@PathVariable("productId") int productId){



    Mono<Account> account =  webClientBuilder.build().get().uri("http://account-service/user/accounts/{userId}/",userId)
                        .retrieve().bodyToMono(Account.class);


    Mono<Product> product = this.ps.findById(productId);

    Mono<Boolean> result = account.zipWith(product,this::isAccountBalanceGreater);


    Mono<ResponseEntity<Product>> p = result.zipWith(product,this::getResponse);

    return p;

    }



    public boolean isAccountBalanceGreater(Account acc, Product prd) {
           return(acc.getBalance()>=prd.getPrice()):
        }




    public ResponseEntity<Product> getResponse(boolean result,Product prod){
        if(result) {

            return ResponseEntity.accepted().body(prod);
        }else {
            return ResponseEntity.badRequest().body(prod);
        }
    }
@PutMapping("/account/update/{accountId}")
    public Mono<ResponseEntity<Account>> updateAccount(@PathVariable("accountId") int accountId, @RequestBody Account account) {


      return as.findById(accountId)
              .flatMap(oldAcc->{
                  oldAcc.setAccountId(account.getAccountId());
                  oldAcc.setAccountId(account.getAccountId());
                    oldAcc.setOwner(account.getOwner());
                    oldAcc.setPin(account.getPin());
                    oldAcc.setBalance(account.getBalance());
                    oldAcc.setUserId(account.getUserId());
                    return ar.save(oldAcc);
              }).map(a -> ResponseEntity.ok(a))
                .defaultIfEmpty(ResponseEntity.notFound().build());


    }

然而,这不起作用,不是错误,只是没有更新。
当我使用测试帐户运行相同的代码时,我的测试用例工作。我不知道这为什么不能执行。有什么建议吗?

您必须将反应式代码视为事件链或回调。所以你需要在其他事情完成后,对你想做的事情做出反应

return webClientBuilder.build()
          .put().uri("http://account-service/account/update/{accountId}",
                         acc.getAccountId())
                         .body(newOwnerAcc,Account.class)
                         .exchange()
                         .thenReturn(true); // if you really need to return a boolean
返回布尔值在被动世界中通常语义不正确。尽量避免if-else语句是很常见的

一种方法是返回一个
Mono
,以标记某个内容已完成,并触发链接到该内容上的内容

public Mono<Void> isAccountBalanceGreater(Account acc, Product prd) {
    return webclient.put()
                    .uri( ... )
                    .retrieve()
                    .bodyToMono(Void.class)
                    .doOnError( // handle error )
 }

// How to call for example
isAccountBalanceGreater(foo, bar)
    .doOnSuccess( ... )
    .doOnError( ... ) 
public Mono isaccountbalancemore(账户账户、产品珠三角){
返回webclient.put()
.uri(…)
.retrieve()
.bodyToMono(无效等级)
.doError(//句柄错误)
}
//例如,如何打电话
isAccountBalanceGreater(foo,bar)
.doOnSuccess(…)
.doon错误(…)

谢谢你的回答,你能帮我更好地理解一下吗。那么你说底部法是更好的选择?如果它返回一个Mono,下一个方法如何知道帐户余额是否更大?一个
Mono
封装了某种将在某个时间点执行的函数。执行
Mono
中的函数后,
Mono
将根据内部函数的结果将其状态更改为(简单解释)已完成或“错误”。因此,在您的情况下,您需要知道的是函数是否运行良好,还是出现问题。你不需要返回一个布尔值,然后计算这个布尔值,你只需要将函数链接到mono,如果mono进入“完成”状态,这些函数就会运行。帐户服务中的put方法也应该返回mono吗?
public Mono<Void> isAccountBalanceGreater(Account acc, Product prd) {
    return webclient.put()
                    .uri( ... )
                    .retrieve()
                    .bodyToMono(Void.class)
                    .doOnError( // handle error )
 }

// How to call for example
isAccountBalanceGreater(foo, bar)
    .doOnSuccess( ... )
    .doOnError( ... )