精講響應式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) 

歡迎關注我的博客,里面有很多精品合集

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM