Spring Webflux:从 Mono 中提取价值

Posted

技术标签:

【中文标题】Spring Webflux:从 Mono 中提取价值【英文标题】:Spring Webflux: Extract value from Mono 【发布时间】:2020-04-30 14:20:36 【问题描述】:

我是 spring webflux 的新手,正在尝试对两个单声道的值执行一些算术运算。我有一个产品服务,它通过 webClient 调用帐户服务来检索帐户信息。我想确定账户的当前余额是否大于或等于产品的价格。

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


//productId is a path variable on method
Mono<Product> product =this.productService.findById(productId);

当我尝试阻止流时出现错误

block()/blockFirst()/blockLast()是阻塞的,线程reactor-http-nio-2不支持

//Causes Error
Double accountBalance = account.map(a->a.getBalance()).block():

Double productPrice = product.map(p->p.getPrice()).block();

///Find difference, send response accordingly....

这是正确的方法吗?还有另一种更好的方法来实现这一目标吗?我也在想一些事情:

Mono<Double> accountBalance = account.map(a->a.getBalance()):

Mono<Double> productPrice = product.map(p->p.getPrice());

Mono<Double> res = accountBalance.zipWith(productPrice,(b,p)-> b-p);

//Something after this.....

【问题讨论】:

【参考方案1】:

您不能在主反应器线程上使用块方法。这是禁止的。 block 在其他线程上发布单声道时可能会起作用,但情况并非如此。

基本上你压缩两个单声道的方法是正确的。您可以创建一些辅助方法来对它们进行计算。在您的情况下,它可能看起来像:

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

然后在您的 Mono 流中,您可以传递方法引用并使其更具可读性。

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

问题是您以后要如何处理这些信息。如果您想返回到您的控制器,只需 truefalse 就可以了。否则,您可能需要一些其他映射、压缩等。

更新

return account.zipWith(productPrice, this::createResponse);

...

ResponseEntity createResponse(Account acc, Product prd) 
   int responseCode = isAccountBalanceGreater(acc, prd) ? 200 : 500;
   return ResponseEntity.status(responseCode).body(prd);

【讨论】:

如果我想返回一些东西怎么办,让我们说一个带有产品主体和适当状态的 responseEntity 正常情况下很容易。将产品单声道映射到 responseEntity 就是这样。请说明帐户余额检查的用途以及在这两种情况下您要做什么。 账户余额检查是看账户里是否有足够的钱购买产品。然后,如果帐户中有足够的内容,它将返回产品以及接受状态或其他适当的状态。如果不够,它会以不同的状态返回。 我添加了一个简单的例子,你如何使用 Spring 响应实体来做到这一点。

以上是关于Spring Webflux:从 Mono 中提取价值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 WebFlux 中的 Mono<List<T>> 中提取内容以将其传递到调用链中

Spring webflux:从请求中消耗单声道或通量

Spring WebFlux Webclient 接收应用程序/八位字节流文件作为 Mono

Spring 5 WebFlux Mono 和 Flux

Spring webflux 反应式 Mono::subscribe

Log Spring webflux 类型 - Mono 和 Flux