精講響應式WebClient第2篇-GET請求阻塞與非阻塞調用方法詳解

本文是精講響應式WebClient第2篇,前篇的blog訪問地址以下:html

在上一篇文章爲你們介紹了響應式IO模型和WebClient的基本用法。本節來繼續深刻的爲你們介紹:如何使用WebClient做爲Http客戶端發送GET請求與進行響應結果的接收。vue

1、block()阻塞式獲取響應結果

WebClient客戶端既支持同步異步、阻塞與非阻塞IO,咱們先來爲你們介紹一下同步阻塞式的編程方式。即:在請求發送以後使用block()方法,阻塞當前線程等待獲取響應結果。java

1.1.使用Mono接收單個對象

建立測試用例,成員變量WebClient,以 "http://jsonplaceholder.typicode.com" 爲訪問服務基礎路徑,該網站是一個免費提供RESTful API進行接口測試的一個網站。web

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響應結果,和咱們經過程序打印出的響應結果數據內容一致。程序控制臺截圖以下:spring

接收響應結果的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條記錄):json


因此咱們須要經過bodyToFlux方法將請求結果轉爲Flux<PostDTO>,經過flux.collectList().block();接收響應數據爲 List<PostDTO>集合。Flux英文含義:流動的,用於接收集合元素響應結果。segmentfault

@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());
}

控制檯打印結果以下:後端

2、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);
}

控制檯打印輸出結果以下:

3、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報文信息詳情控制檯打印結果

4、佔位符傳參

非佔位符傳參,寫死的參數方式不靈活

.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)

歡迎關注個人博客,裏面有不少精品合集

  • 本文轉載註明出處(必須帶鏈接,不能只轉文字):字母哥博客

以爲對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創做動力! 。另外,筆者最近一段時間輸出了以下的精品內容,期待您的關注。

相關文章
相關標籤/搜索