如何使用 Spring5 WebClient 进行异步调用

Posted

技术标签:

【中文标题】如何使用 Spring5 WebClient 进行异步调用【英文标题】:How to make an asynchronous call using Spring5 WebClient 【发布时间】:2020-03-16 09:14:10 【问题描述】:

我是 Spring Reactive 框架的新手,并尝试使用 Spring5 WebClient 进行异步调用。 我能够成功地进行与同步相同的调用。但面临异步调用的问题。

我正在使用以下代码进行异步调用:

Mono<ClientResponse> reponse = WebClient.builder().build().post()
.uri("http://api.com")
.body(BodyInserters.fromObject("data"))
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer blahblahblahblah")
.exchange();

// couple of logger messages and other statements

问题是它没有执行 API 调用并且没有给出响应。它继续执行其他语句,但它从不调用 API 调用。

我不想使用block() 方法,因为它会将其转换为同步调用。

我搜索了很多网站和文档,但异步调用使用的是相同的代码。但不确定为什么它不起作用。如果我错过了什么,谁能帮助我?

【问题讨论】:

如果这是一个 webflux 应用程序,您可能不应该订阅。发起呼叫的是订户。因此,如果有一个调用客户端,那么该调用客户端应该是订阅者。请发布您的完整代码。 【参考方案1】:

您可以使用 subscribe() 函数进行异步调用。希望它有效..

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

下面的代码可以工作。

Mono<ClientResponse> reponse =
WebClient.builder().build().post()
.uri("http://api.com")
.body(BodyInserters.fromObject("data"))
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer blahblahblahblah")
.bodyToMono(ClientResponse.class)
.retrieve();

【讨论】:

【参考方案3】:

您需要订阅结果。这可以通过block() call 来完成:

订阅此 Mono 并无限期阻止,直到收到下一个信号。返回该值,如果 Mono 完成为空,则返回 null。如果 Mono 错误,则抛出原始异常(如果是已检查异常,则将其包装在 RuntimeException 中)。

没有订阅,调用不会被设计执行。但是,您可以在其他流中传递准备好的单声道来组合它们,但要获得结果,您必须在某处调用终止操作。

【讨论】:

感谢您的回复,但正如我在问题中提到的那样,我不想使用 block() 作为同步调用。异步调用还有其他可能性吗? subscribe + onComplete。或者只是toFuture 我正在使用此链接***.com/questions/50223891/… 中建议的 subscribe()。如何将 onComplete 与 subscribe 一起使用? 我不赞成这个答案,因为它还没有确定订阅者应该是谁。他的应用程序是客户端还是任何其他客户端是实际订阅者。在确定此信息之前,此答案不是正确答案。

以上是关于如何使用 Spring5 WebClient 进行异步调用的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用从 Spring5 的 WebClient 返回的 Flux 的 block() 方法吗?

Spring5之WebClient简单使用

使用 ssl 的 Spring 5 WebClient

Spring WebClient:如何将大字节 [] 流式传输到文件?

Spring WebClient 使用简介

Spring WebClient 使用简介