如何使用 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
如何使用 WebClient 反应式 Web 客户端发送带有 zip 正文的 POST 请求