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

