精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方法详解
本文是精讲响应式WebClient第2篇,前篇的blog访问地址如下:
在上一篇文章为大家介绍了响应式IO模型和WebClient的基本用法。本节来继续深入的为大家介绍:如何使用WebClient作为Http客户端发送GET请求与进行响应结果的接收。
一、block()阻塞式获取响应结果
WebClient客户端既支持同步异步、阻塞与非阻塞IO,我们先来为大家介绍一下同步阻塞式的编程方式。即:在请求发送之后使用block()方法,阻塞当前线程等待获取响应结果。
1.1.使用Mono接收单个对象
创建测试用例,成员变量WebClient,以 "http://jsonplaceholder.typicode.com" 为访问服务基础路径,该网站是一个免费提供RESTful API进行接口测试的一个网站。
public class GetTest {
//创建webClient
private WebClient webClient = WebClient.builder()
.baseUrl("http://jsonplaceholder.typicode.com")
.build();
@Test
public void testMono() {
Mono<PostDTO> mono = webClient
.get() // 发送GET 请求
.uri("/posts/1") //服务请求路径,基于baseurl
.retrieve() // 获取响应体
.bodyToMono(PostDTO.class); //响应数据类型转换
System.out.println(mono.block());
}
}
- get() 方法表示使用HTTP GET method
- uri() 指定服务接口路径,以baseurl为基础
- retrieve() 获取响应体,即HTTP body
- bodyToMono()将响应体转换为一个对象,Mono英文是单声道、单体的意思,用于接收单个对象
通过浏览器访问 "http://jsonplaceholder.typicode.com/posts/1" 得到JSON响应结果,和我们通过程序打印出的响应结果数据内容一致。程序控制台截图如下:
接收响应结果的java POJO实体对象如下:
import lombok.Data;
@Data
public class PostDTO {
private int userId;
private int id;
private String title;
private String body;
}
1.2.使用Flux接收集合对象
访问http://jsonplaceholder.typicode.com/posts 可以获得JSON数组方式的请求结果如图(一共100条我截图截取3条记录):
所以我们需要通过bodyToFlux方法将请求结果转为Flux<PostDTO>
,通过flux.collectList().block();
接收响应数据为 List<PostDTO>
集合。Flux英文含义:流动的,用于接收集合元素响应结果。
@Test
public void testFlux() {
Flux<PostDTO> flux = webClient
.get() // 发送GET 请求
.uri("/posts") //服务请求路径,基于baseurl
.retrieve() // 获取响应体
.bodyToFlux(PostDTO.class); //响应数据类型转换
List<PostDTO> posts = flux.collectList().block();
assert posts != null;
System.out.println("获取posts集合元素数量:" + posts.size());
}
控制台打印结果如下:
二、subscribe()非阻塞式获取响应结果
与block()阻塞式获取响应结果不同,使用subscribe()异步订阅响应结果,不会阻塞主线程继续向下执行。获取到响应结果之后,由回调函数handleResponse处理响应结果。
@Test
public void testSubscribe() throws InterruptedException {
Mono<PostDTO> mono = webClient
.get() // 发送GET 请求
.uri("/posts/1") //服务请求路径,基于baseurl
.retrieve() // 获取响应体
.bodyToMono(PostDTO.class); //响应数据类型转换
//异步非阻塞处理响应结果
mono.subscribe(GetTest::handleResponse);
//为了避免测试用例主线程执行完成,导致看不到异步处理结果
Thread.currentThread().sleep(10000);
}
//响应结果处理回调方法
private static void handleResponse(PostDTO postDTO) {
System.out.println("handle response:=======================");
System.out.println(postDTO);
}
控制台打印输出结果如下:
三、exchange()获取HTTP响应完整内容
上文中retrieve()只能获取HTTP报文中的Body,也就是响应体。如果我们想获取HTTP报文中的状态码、headers、cookies等信息,需要使用exchange()方法。
@Test
public void testExchange() {
Mono<ClientResponse> mono = webClient
.get() // 发送GET 请求
.uri("/posts/1") //服务请求路径,基于baseurl
.exchange();
System.out.println(mono.block());
// 获取完整的响应对象
ClientResponse response = mono.block();
assert response != null;
HttpStatus httpStatus = response.statusCode(); // 获取响应状态
int statusCodeValue = response.rawStatusCode(); // 获取响应状态码
ClientResponse.Headers headers = response.headers(); // 获取响应头
// 获取响应体
Mono<PostDTO> resultMono = response.bodyToMono(PostDTO.class);
PostDTO postDTO = resultMono.block();
// 输出结果
System.out.println("响应状态:" + httpStatus);
System.out.println("响应状态码值:" + statusCodeValue);
System.out.println("HTTP Headers:" + headers.asHttpHeaders());
System.out.println("响应体:" + postDTO);
}
HTTP报文信息详情控制台打印结果
四、占位符传参
非占位符传参,写死的参数方式不灵活
.uri("/posts/1") //服务请求路径,基于baseurl
第一种占位符传参:数字顺序占位符
Mono<String> mono = webClient.uri("/{1}/{2}", "posts", "1")
第二种占位符传参:参数名称占位符
String type = "posts";
int id = 1;
Mono<String> mono = webClient.uri("/{type}/{id}", type, id)
第三种通过map传参
Map<String,Object> map = new HashMap<>();
map.put("type", "posts");
map.put("id", 1);
Mono<String> mono = webClient
.uri("/{type}/{id}", map)
喜欢 (1)or分享 (0)
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例
- RTSP/GB28181/HIKSDK/Ehome协议视频上云服务平台EasyCVR人脸识别开发ArcSoftFace环境搭建
- RTSP/GB28181/HIKSDK/EHome流媒体协议视频上云网关EasyCVR流地址密码不正确如何修正?
- tmux终端意外出现控制字符
- clickhouse编译安装以及搭建mysql实时复制
- Linux回收站机制实现过程及用法详解
- Linux如何基于AIDE检测文件系统完整性
- MySQL压测时Linux中断异常飚高,原来是因为...
- Ubuntu20.04防火墙设置简易教程(小白)
- linux上搭建私有Git服务器的详细教程
- Centos7 安装 Mysql8教程
- linux下快速列出局域网中所有主机名(计算机名)的脚本
- 详解Linux重定向用法
- Zabbix基于snmp实现监控linux主机
- 快速解决linux下中文输入法问题
- Linux实现文件内容去重及求交并差集