【WEB系列】WebClient之retrieve与exchange的使用区别介绍

文章目录
  1. I. 项目环境
    1. 1. 依赖
    2. 2. REST接口
  2. II. 实例演示
    1. 1. exchange使用实例
    2. 2. retrieve使用实例
    3. 3. 小结
  3. II. 其他
    1. 0. 项目
    2. 1. 一灰灰Blog

前面介绍了几篇WebCilent的使用姿势博文,其中大部分的演示case,都是使用retrieve来获取返回ResponseBody,我国我们希望获取更多的返回信息,比如获取返回头,这个时候exchange则是更好的选择;

本文将主要介绍一下,在WebClient中retrieve和exchange的各自使用场景

I. 项目环境

本项目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA进行开发

1. 依赖

使用WebClient,最主要的引入依赖如下(省略掉了SpringBoot的相关依赖,如对于如何创建SpringBoot项目不太清楚的小伙伴,可以关注一下我之前的博文)

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2. REST接口

添加一个简单的Rest接口,用于后续的测试

1
2
3
4
@GetMapping(path = "get")
public Mono<String> get(String name, Integer age) {
return Mono.just("req: " + name + " age: " + age);
}

II. 实例演示

通过前面的几篇学习,我们知道WebClient发起请求的一般使用姿势如下

1
2
Mono<ClientResponse> res = webCient.get().uri(xxx).exchange()
WebClient.ResponseSpec responseSpec = webClient.get().uri(xxx).retrieve()

这两个方法都是用来获取返回结果的,最大的区别在于通过exchange接收完整的ResponseEntity;而retrieve接收的则是ResponseBody

1. exchange使用实例

The exchange() method provides more control than the retrieve method, provides access to the ClientResponse

下面给出一个简单的,获取返回的状态码,cookies等请求头信息的case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
WebClient webClient = WebClient.create("http://127.0.0.1:8080");

// 返回结果
Mono<ClientResponse> res = webClient.get().uri("/get?name={1}&age={2}", "一灰灰", 18).exchange();
res.subscribe(s -> {
HttpStatus statusCode = s.statusCode();
ClientResponse.Headers headers = s.headers();
MultiValueMap<String, ResponseCookie> ans = s.cookies();
s.bodyToMono(String.class).subscribe(body -> {
System.out.println(
"response detail: \nheader: " + headers.asHttpHeaders() + "\ncode: " + statusCode + "\ncookies: " + ans +
"\nbody:" + body);
});
});

上面这段代码中,主要的核心点就是ClientResponse的解析,可以直接通过它获取返回头,响应状态码,其次提供了一些对ResponseBody的封装调用

返回结果

1
2
3
4
5
response detail: 
header: [Content-Type:"text/plain;charset=UTF-8", Content-Length:"22"]
code: 200 OK
cookies: {}
body:req: 一灰灰 age: 18

如果我们只关注ResponseBody,用exchange也是可以直接写的,如下,相比retrieve稍微饶了一道

1
2
3
4
Mono<String> result = client.get()
.uri("/get?name={1}&age={2}", "一灰灰", 18).accept(MediaType.APPLICATION_JSON)
.exchange()
.flatMap(response -> response.bodyToMono(String.class));

另外一个更加推荐的写法是直接返回Mono<ResponseEntity<?>>,更友好的操作姿势,返回结果如下

1
2
3
4
response detail2: 
code: 200 OK
headers: [Content-Type:"text/plain;charset=UTF-8", Content-Length:"22"]
body: req: 一灰灰 age: 18

2. retrieve使用实例

The retrieve() method is the easiest way to get a response body and decode it.

前面已经多次演示retrieve的使用姿势,基本上是在后面带上bodyToMonobodyToFlux来实现返回实体的类型转换

1
2
3
4
WebClient webClient = WebClient.create("http://127.0.0.1:8080");

Mono<String> ans = webClient.get().uri("/get?name={1}", "一灰灰").retrieve().bodyToMono(String.class);
ans.subscribe(s -> System.out.println("basic get with one argument res: " + s));

3. 小结

对于retrieve与exchange来说,最简单也是最根本的区别在于,是否需要除了ResponseBody之外的其他信息

  • 如果只关注ResponseBody: 推荐使用retrieve
  • 如果还需要获取其他返回信息: 请选择exchange

II. 其他

0. 项目

系列博文

源码

1. 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

一灰灰blog


打赏 如果觉得我的文章对您有帮助,请随意打赏。
分享到