Spring?Boot?3.x?中?WebClient?示例詳解析
Spring Boot 3.x 中 WebClient 全面詳解及示例
1. WebClient 簡(jiǎn)介
- 定義:Spring 5 引入的響應(yīng)式 HTTP 客戶端,用于替代
RestTemplate
(已棄用),支持異步非阻塞的 HTTP 請(qǐng)求。 - 核心特性:
- 支持所有 HTTP 方法(GET/POST/PUT/DELETE 等)。
- 靈活配置請(qǐng)求頭、請(qǐng)求體、URI 參數(shù)。
- 直接返回
Mono<ResponseEntity>
或Flux
獲取響應(yīng)細(xì)節(jié)。 - 支持鏈?zhǔn)秸{(diào)用和響應(yīng)式流處理。
- 依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
2. 示例代碼詳解
示例 1:GET 請(qǐng)求(帶請(qǐng)求頭,獲取狀態(tài)碼和響應(yīng)頭)
// 1. 創(chuàng)建 WebClient 實(shí)例 WebClient webClient = WebClient.builder() .baseUrl("http://api.example.com") .build(); // 2. 發(fā)送 GET 請(qǐng)求 Mono<ResponseEntity<User>> responseMono = webClient.get() .uri("/users/{id}", 123) // 路徑參數(shù) .header("Authorization", "Bearer token_123") // 添加請(qǐng)求頭 .retrieve() // 開始發(fā)送請(qǐng)求 .toEntity(User.class); // 轉(zhuǎn)換響應(yīng)體為 User 對(duì)象 // 3. 處理響應(yīng) responseMono.block().ifPresent(response -> { int statusCode = response.getStatusCode().value(); // 狀態(tài)碼 HttpHeaders headers = response.getHeaders(); // 響應(yīng)頭 User user = response.getBody(); // 響應(yīng)體 });
示例 2:POST 請(qǐng)求(傳遞 JSON 請(qǐng)求體)
// 1. 創(chuàng)建請(qǐng)求體對(duì)象 User newUser = new User("John", 25); // 2. 發(fā)送 POST 請(qǐng)求 Mono<ResponseEntity<String>> responseMono = webClient.post() .uri("/users") .contentType(MediaType.APPLICATION_JSON) // 設(shè)置 Content-Type .bodyValue(newUser) // 請(qǐng)求體(自動(dòng)序列化為 JSON) .retrieve() .toEntity(String.class); // 返回響應(yīng)體(如成功返回 "Created") // 3. 處理響應(yīng) String locationHeader = responseMono.block().getHeaders().getFirst("Location"); // 獲取 Location 頭
示例 3:PUT/PATCH 請(qǐng)求(更新資源)
// 1. 更新對(duì)象 User updatedUser = new User("John Doe", 26); // 2. 發(fā)送 PUT 請(qǐng)求 Mono<Void> responseMono = webClient.put() .uri("/users/123") .contentType(MediaType.APPLICATION_JSON) .bodyValue(updatedUser) .retrieve() .toBodilessEntity(); // 無響應(yīng)體時(shí)使用 // 3. 檢查狀態(tài)碼 responseMono.block(); // 若無異常,則成功
示例 4:DELETE 請(qǐng)求
Mono<Void> responseMono = webClient.delete() .uri("/users/123") .retrieve() .toBodilessEntity(); // 檢查狀態(tài)碼(如 204 No Content) responseMono.block();
示例 5:自定義響應(yīng)類型(如 Map)
Mono<ResponseEntity<Map<String, Object>>> responseMono = webClient.get() .uri("/data") .retrieve() .toEntity(new ParameterizedTypeReference<Map<String, Object>>() {}); Map<String, Object> data = responseMono.block().getBody();
示例 6:使用響應(yīng)提取器定制返回
// 自定義提取器:提取響應(yīng)體中的某個(gè)字段 Mono<String> customHeaderMono = webClient.get() .uri("/headers") .retrieve() .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new RuntimeException("Client error"))) .header("X-Custom-Header") // 直接提取指定頭 .switchIfEmpty(Mono.just("Default")); String customHeader = customHeaderMono.block();
示例 7:批量操作(查詢多個(gè)資源)
// 1. 構(gòu)建帶查詢參數(shù)的 URI Mono<User[]> responseMono = webClient.get() .uri(uriBuilder -> uriBuilder .path("/users") .queryParam("page", 1) .queryParam("size", 10) .build()) .retrieve() .bodyToMono(User[].class); // 返回?cái)?shù)組 User[] users = responseMono.block();
3. 核心方法對(duì)比表格
方法 | HTTP 方法 | 返回類型 | 關(guān)鍵代碼片段 | 適用場(chǎng)景 |
---|---|---|---|---|
get() | GET | Mono<User> | webClient.get().uri("/users/1").retrieve().bodyToMono(User.class); | 簡(jiǎn)單 GET 請(qǐng)求,直接返回對(duì)象 |
retrieve().toEntity() | GET | Mono<ResponseEntity<User>> | webClient.get().uri("/users/1").retrieve().toEntity(User.class); | 需獲取狀態(tài)碼或響應(yīng)頭 |
post().bodyValue() | POST | Mono<String> | webClient.post().bodyValue(newUser).retrieve().bodyToMono(String.class); | 發(fā)送 JSON 請(qǐng)求體,直接返回結(jié)果 |
put().retrieve().toBodilessEntity() | PUT | Mono<Void> | webClient.put().uri("/users/1").retrieve().toBodilessEntity(); | 更新資源,無響應(yīng)體 |
delete() | DELETE | Mono<Void> | webClient.delete().uri("/users/1").retrieve().toBodilessEntity(); | 刪除資源 |
4. 關(guān)鍵配置與注意事項(xiàng)
設(shè)置超時(shí):
WebClient webClient = WebClient.builder() .timeout(Duration.ofSeconds(5)) .build();
異常處理:
Mono<User> response = webClient.get() .uri("/users/invalid") .retrieve() .onStatus(HttpStatus::is4xxClientError, clientResponse -> Mono.error(new CustomException())) .bodyToMono(User.class);
自定義序列化:
ObjectMapper objectMapper = new ObjectMapper(); WebClient webClient = WebClient.builder() .codecs(configurer -> configurer.defaultCodecs() .jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper))) .build();
5. 總結(jié)對(duì)比表格
需求 | 實(shí)現(xiàn)方法 | 關(guān)鍵代碼 | 注意事項(xiàng) |
---|---|---|---|
發(fā)送 JSON 請(qǐng)求體 | 使用 bodyValue() 或 body(BodyInserter) | .contentType(MediaType.APPLICATION_JSON).bodyValue(newUser); | 確保序列化配置正確 |
獲取狀態(tài)碼和響應(yīng)頭 | 返回 ResponseEntity | .retrieve().toEntity(User.class) | 處理 2xx/4xx/5xx 狀態(tài)碼 |
自定義響應(yīng)類型 | 使用 ParameterizedTypeReference 或泛型 | .bodyToMono(new ParameterizedTypeReference<List<User>>() {}) | 處理復(fù)雜泛型類型 |
響應(yīng)提取器定制 | 使用 .header() 、.bodyToMono() 或自定義轉(zhuǎn)換邏輯 | .header("X-Custom-Header").switchIfEmpty(Mono.just("Default")); | 簡(jiǎn)化復(fù)雜響應(yīng)處理邏輯 |
關(guān)鍵總結(jié)
- 核心類:
WebClient
:核心客戶端,支持鏈?zhǔn)秸{(diào)用。Mono/Flux
:響應(yīng)式類型,處理異步響應(yīng)。ResponseEntity
:封裝響應(yīng)頭、狀態(tài)碼和體。
- 最佳實(shí)踐:
- 使用
retrieve()
統(tǒng)一處理響應(yīng)。 - 通過
.onStatus()
處理異常狀態(tài)碼。 - 自定義
Codecs
配置序列化器。
- 使用
- 響應(yīng)式特性:
- 非阻塞 I/O,適合高并發(fā)場(chǎng)景。
- 需用
block()
或subscribe()
處理異步結(jié)果(生產(chǎn)環(huán)境建議用非阻塞方式)。
通過以上示例和配置,開發(fā)者可以高效實(shí)現(xiàn) REST API 的全場(chǎng)景調(diào)用需求,充分利用 Spring WebFlux 的響應(yīng)式優(yōu)勢(shì)。
到此這篇關(guān)于Spring Boot 3.x 中 WebClient 全面詳解及示例的文章就介紹到這了,更多相關(guān)springboot webclient內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea項(xiàng)目啟動(dòng)報(bào)錯(cuò),日志包沖突slf4j和logback沖突問題
遇到SLF4J沖突時(shí),可以嘗試移除沖突的綁定或調(diào)整項(xiàng)目依賴,具體方法包括刪除多余的Logger綁定庫,如Logback或Log4j,或在項(xiàng)目配置文件中明確指定使用的日志框架,若使用WebLogic服務(wù)器,需在weblogic.xml中進(jìn)行特定配置,適當(dāng)調(diào)整pom.xml文件中的依賴版本也可能解決問題2024-09-09Java SpringBoot啟動(dòng)指定profile的8種方式詳解
這篇文章主要介紹了spring boot 如何指定profile啟動(dòng)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Java控制臺(tái)版五子棋的簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Java控制臺(tái)版五子棋的簡(jiǎn)單實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01SpringSecurity學(xué)習(xí)之自定義過濾器的實(shí)現(xiàn)代碼
這篇文章主要介紹了SpringSecurity學(xué)習(xí)之自定義過濾器的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01詳述 DB2 分頁查詢及 Java 實(shí)現(xiàn)的示例
本篇文章主要介紹了詳述 DB2 分頁查詢及 Java 實(shí)現(xiàn)的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09SpringBoot整合Netty開發(fā)MQTT服務(wù)端
Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)開發(fā)的網(wǎng)絡(luò)通信框架,本文主要介紹了SpringBoot如何整合Netty開發(fā)MQTT服務(wù)端,感興趣的小伙伴可以了解下2025-07-07