Spring Boot Webclient 的检索与交换

Abd*_*han 21 reactive-programming spring-boot spring-webclient

我最近开始WebClient在我的Spring boot项目中使用。有人可以扔之间的差异/用法一些轻exchangeretrieve方法WebClient

我明白exchange返回Mono<ClientResponse>retrieve返回ResponseSpec,我只想知道何时/为什么我应该使用它们中的每一个。

非常感谢。

小智 15

根据spring Webclient api 文档,两者之间的区别在于,交换检索除正文之外的其他 http 响应信息(如标头和状态),而检索仅返回正文信息。

所以如果你只需要body信息你应该使用retrieve,因为它是交换然后获取body的快捷方式,但是如果你需要其他信息比如http状态你必须使用exchange。

  • 如果有人忽略的话,文档中的重要说明注意:与retrieve()不同,当使用exchange()时,应用程序有责任使用任何响应内容,无论场景如何(成功、错误、意外数据等)。不这样做可能会导致内存泄漏。有关使用主体的所有可用选项的列表,请参阅 ClientResponse。通常更喜欢使用retrieve(),除非您有充分的理由使用exchange(),它允许在决定如何或是否使用响应之前检查响应状态和标头。 (2认同)

Abd*_*han 11

添加到@JArgente 的答案。

根据该retrieve()方法的官方文档:

执行 HTTP 请求并检索响应正文

...

此方法是使用 exchange() 并通过 ClientResponse 解码响应正文的快捷方式。

exchange()方法

执行 HTTP 请求并返回带有响应状态和标头的 ClientResponse 。然后,您可以使用响应方法来消耗主体:


retrieve()方法对ClientResponse对象进行解码,并将现成的对象交给您以供您使用。它没有一个很好的 api 来处理异常。

然而,另一方面,该exchange()方法将 ClientResponse 对象本身以及响应状态和标头交给您。使用交换方法,您可以获得对响应对象的细粒度控制以及处理响应对象和异常的更好方法。

如果您只想使用一些 api,请使用retrieve().

如果您想更好地控制响应对象、标头和异常,请使用exchange().


更新 1

Spring 5.3开始,由于可能存在内存/连接泄漏,该exchange()方法已被弃用。或者可以代替。exchangeToMono()exchangeToFlux()

感谢@rhubarb的更新。

  • 请注意,“exchange()”[自 5.3 起已弃用](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient. RequestHeadersSpec.html#exchange--) 支持 `exchangeToMono()` 或 `exchangeToFlux()` (3认同)