繁体   English   中英

Spring webflux:webClient put 调用

[英]Spring webflux : webClient put call

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

@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);
        }
    }

我在帐户服务中的 put 方法也可以正常工作:

@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());


    }

现在我希望能够更新余额,我在 isAccountBalancerGreater 方法中尝试了这个:

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

               double newBuyerBalance  =acc.getBalance() - prd.getPrice();

                Account newOwnerAcc = new Account(acc.getAccountId(),acc.getOwner(),acc.getPin(),newBuyerBalance,acc.getUserId());


                this.ps.removeProduct(prd.getProductId());


  webClientBuilder.build().put().uri("http://account-service/account/update/{accountId}",acc.getAccountId()).body(newOwnerAcc,Account.class).exchange();



              return true;
           }
           return false;
        }

但是这不起作用,不是错误只是没有更新。 当我使用测试帐户运行相同的代码时,我的测试用例有效。 我不确定为什么这没有执行。 有什么建议?

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

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<Void>以标记某事已完成,并触发链接到其上的某事。

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 String wcPut(){

    Map<String, String> bodyMap = new HashMap();
    bodyMap.put("key1","value1");
 

    WebClient client = WebClient.builder()
            .baseUrl("domainURL")
            .build();


    String responseSpec = client.put()
            .uri("URI")
            .headers(h -> h.setBearerAuth("token if any"))
            .body(BodyInserters.fromValue(bodyMap))
            .exchange()
            .flatMap(clientResponse -> {
                if (clientResponse.statusCode().is5xxServerError()) {
                    clientResponse.body((clientHttpResponse, context) -> {
                        return clientHttpResponse.getBody();
                    });
                    return clientResponse.bodyToMono(String.class);
                }
                else
                    return clientResponse.bodyToMono(String.class);
            })
            .block();

    return responseSpec;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM