本文是精講響應式WebClient第2篇,前篇的blog訪問地址以下:html
在上一篇文章爲你們介紹了響應式IO模型和WebClient的基本用法。本節來繼續深刻的爲你們介紹:如何使用WebClient做爲Http客戶端發送GET請求與進行響應結果的接收。vue
WebClient客戶端既支持同步異步、阻塞與非阻塞IO,咱們先來爲你們介紹一下同步阻塞式的編程方式。即:在請求發送以後使用block()方法,阻塞當前線程等待獲取響應結果。java
建立測試用例,成員變量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()); } }
經過瀏覽器訪問 "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; }
訪問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()); }
控制檯打印結果以下:後端
與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); }
控制檯打印輸出結果以下:
上文中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)
以爲對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創做動力! 。另外,筆者最近一段時間輸出了以下的精品內容,期待您的關注。