春季网络通量:网络客户端放置调用



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

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

}

现在我希望能够更新余额,我已经在isAccountBalancerGreat方法中尝试过这个:

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( ... ) 

最新更新