简体   繁体   English

Spring webflux:webClient put 调用

[英]Spring webflux : webClient put call

I have an account service and a product service communicating.我有一个帐户服务和一个产品服务通信。 When a request comes from a user to purchase a product (I did not include the user service, it is working fine and not the issue), the product service checks to see if there are enough funds in the account, and if there is it updates the balances.当用户请求购买产品时(我没有包括用户服务,它工作正常而不是问题),产品服务检查帐户中是否有足够的资金,如果有更新余额。 The following code works fine:以下代码工作正常:

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

My put method in the account service also works fine:我在帐户服务中的 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());


    }

Now I want to be able to update the balances, I have tried this in the isAccountBalancerGreater method:现在我希望能够更新余额,我在 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;
        }

However this does not work, not error just nothing updates.但是这不起作用,不是错误只是没有更新。 My test case works when I run the same code with a test account.当我使用测试帐户运行相同的代码时,我的测试用例有效。 I'm not sure why this is not executing.我不确定为什么这没有执行。 Any suggestions?有什么建议?

you have to think of reactive code as event chains or callbacks.您必须将反应式代码视为事件链或回调。 So you need to respond to what you want something to do, after some other thing has been completed.因此,您需要在其他事情完成后对您想要做的事情做出回应。

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

return a boolean is usually not semantically correct in a reactive world.在反应世界中,返回一个布尔值通常在语义上是不正确的。 Its very common to try to avoid if-else statements试图避免 if-else 语句是很常见的

One way is to return a Mono<Void> to mark that something has been completed, and trigger something chained onto it.一种方法是返回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( ... ) 

You can try like following:您可以尝试如下:

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.

相关问题 如何模拟 Spring WebFlux WebClient? - How to mock Spring WebFlux WebClient? Spring webflux with webclient bodyToMono UnsupportedMediaTypeException 不支持内容类型“application/json” - Spring webflux with webclient bodyToMono UnsupportedMediaTypeException Content type 'application/json' not supported 如何在错误 Spring WebFlux 上调用另一个 api - How to call another api on error Spring WebFlux 在Spring Framework中使用WebClient进行REST调用时出错 - Error in REST call using WebClient in Spring Framework WebFlux 调用与 WebClient 返回 IllegalStateException 只允许一个连接接收订阅者 - WebFlux call with WebClient returning IllegalStateException Only one connection receive subscriber allowed Spring WebClient put Mapping:不支持内容类型&#39;application / json&#39; - Spring WebClient put Mapping: Content type 'application/json' not supported Spring Boot Webclient - 等待多重调用的结束响应 - Spring Boot Webclient - wait end response of multi call Azure REST WebClient PUT Blob - Azure REST WebClient PUT Blob spring webflux流完成消费者 - spring webflux stream Completion Consumer 如何模拟 Spring WebClient 和构建器 - How to mock Spring WebClient and builder
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM