如何使用 WebClient 使用响应式 Spring Rest API

Posted

技术标签:

【中文标题】如何使用 WebClient 使用响应式 Spring Rest API【英文标题】:How to consume a Reactive Spring Rest API with WebClient 【发布时间】:2017-10-25 01:36:42 【问题描述】:

我需要在后端作业(可执行 jar)上使用反应式休息 API(使用 spring webflux 构建)。

我读过 Spring WebClient,但有些地方我不明白。

例如:

WebClient webClient = WebClient.create("http://localhost:8080");

Mono<Person> person = webClient.get()
        .uri("/persons/id", 42)
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .then(response -> response.bodyToMono(Person.class));

在最后一行,有一个“bodyToMono”。所以这是我的问题:

如果调用的 Rest API 已经是响应式服务,我是否需要将响应转换为单声道?有什么我遗漏的地方吗?

从我的角度来看,我认为可以有办法在代码中明确说明我的 Rest API 是反应式的,但可能是我不知道的事情。

【问题讨论】:

【参考方案1】:

是的,它是必需的。 响应式的整个想法是确保没有一个线程被 IO 阻塞。

您可能已经使服务器端服务反应了,但是当您使用该服务时,当您的客户端被阻止直到服务器响应时,您将获得什么好处。您的客户端线程一直等待,直到服务器响应。这是不希望的。

webClient.get()
        .uri("/persons/id", 42)
        .accept(MediaType.APPLICATION_JSON)
        .exchange().block()

将阻止您当前的客户端线程等待服务器响应。这可能会阻塞您的客户端线程。

webClient.get()
        .uri("/persons/id", 42)
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .then(response -> response.bodyToMono(Person.class));

为您提供一个 Mono,它是对将来可以发出单个值的发布者的引用。所以客户端线程是非阻塞的。

我在博客中对此进行了更多解释。 https://dzone.com/articles/spring-5-reactive-web-services

【讨论】:

感谢您的详细解释。我现有的 REST API 正在返回一个 ResponseBodyEmitter,我正在尝试编写一个客户端来获取异步响应。我可以为此使用这个响应式 WebClient 吗?

以上是关于如何使用 WebClient 使用响应式 Spring Rest API的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring 响应式 WebClient 中返回 Kotlin Coroutines Flow

Spring Boot响应式WebClient调用遗留端点

如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求

Srping 响应式框架 WebFlux 的性能小测试_WebClient连接池

反应式 WebClient 未发出响应

Spring WebClient与RestTemplate性能对比——响应式Spring的道法