关于spring:精讲响应式WebClient第2篇GET请求阻塞与非阻塞调用方法详解

13次阅读

共计 3512 个字符,预计需要花费 9 分钟才能阅读完成。

本文是精讲响应式 WebClient 第 2 篇,前篇的 blog 拜访地址如下:

  • 精讲响应式 webclient 第 1 篇 - 响应式非阻塞 IO 与根底用法

在上一篇文章为大家介绍了响应式 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) 

欢送关注我的博客,外面有很多精品合集

  • 本文转载注明出处(必须带连贯,不能只转文字):字母哥博客。

感觉对您有帮忙的话,帮我点赞、分享!您的反对是我不竭的创作能源!。另外,笔者最近一段时间输入了如下的精品内容,期待您的关注。

  • 《手摸手教你学 Spring Boot2.0》
  • 《Spring Security-JWT-OAuth2 一本通》
  • 《实战前后端拆散 RBAC 权限管理系统》
  • 《实战 SpringCloud 微服务从青铜到王者》
  • 《VUE 深入浅出系列》
正文完
 0