重學SpringBoot3-WebClient配置與使用詳解

更多SpringBoot3內容請關注我的專欄:《SpringBoot3》
期待您的點贊??收藏評論

重學SpringBoot3-WebClient配置與使用詳解
  • 1. 簡介
  • 2. 環境準備
    • 2.1 依賴配置
  • 3. WebClient配置
    • 3.1 基礎配置
    • 3.2 高級配置
    • 3.3 retrieve()和exchange()區別
  • 4. 使用示例
    • 4.1 基本請求操作
    • 4.2 處理復雜響應
    • 4.3 高級用法
  • 5. 最佳實踐
  • 6. 注意事項
  • 7. 與RestTemplate對比
  • 8. 總結
  • 參考資料

1. 簡介

WebClient是Spring 5引入的響應式Web客戶端,用于執行HTTP請求。相比傳統的RestTemplate,WebClient提供了非阻塞、響應式的方式來處理HTTP請求,是Spring推薦的新一代HTTP客戶端工具。本文將詳細介紹如何在SpringBoot 3.x中配置和使用WebClient。

2. 環境準備

2.1 依賴配置

pom.xml中添加必要的依賴:

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.10</version><relativePath/> <!-- lookup parent from repository --></parent><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>

3. WebClient配置

3.1 基礎配置

@Configuration
public class WebClientConfig {@Beanpublic WebClient webClient() {return WebClient.builder().baseUrl("https://echo.apifox.com").defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).build();}
}

3.2 高級配置

package com.coderjia.boot3webflux.config;import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;import java.time.Duration;/*** @author CoderJia* @create 2024/12/3 下午 09:42* @Description**/
@Slf4j
@Configuration
public class WebClientConfig {@Beanpublic WebClient webClient() {// 配置HTTP連接池ConnectionProvider provider = ConnectionProvider.builder("custom").maxConnections(500).maxIdleTime(Duration.ofSeconds(20)).build();// 配置HTTP客戶端HttpClient httpClient = HttpClient.create(provider).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000).responseTimeout(Duration.ofSeconds(5)).doOnConnected(conn ->conn.addHandlerLast(new ReadTimeoutHandler(5)).addHandlerLast(new WriteTimeoutHandler(5)));// 構建WebClient實例return WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).baseUrl("https://echo.apifox.com").defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)// 添加請求日志記錄功能.filter(ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {log.debug("Request: {} {}",clientRequest.method(),clientRequest.url());return Mono.just(clientRequest);}))// 添加響應日志記錄功能.filter(ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {log.debug("Response status: {}",clientResponse.statusCode());return Mono.just(clientResponse);})).build();}
}

3.3 retrieve()和exchange()區別

在使用 WebClient 進行 HTTP 請求時,retrieve() 和 exchange() 方法都可以用來處理響應,但它們有不同的用途和行為。以下是它們的主要區別:
retrieve()

  • 用途:retrieve() 方法用于簡化響應處理,特別是當你只需要響應體時。
  • 自動錯誤處理:retrieve() 會自動處理 HTTP 錯誤狀態碼(例如 4xx 和 5xx),并拋出 WebClientResponseException 及其子類。
  • 返回值:通常用于直接獲取響應體,例如 bodyToMono(String.class) 或 bodyToFlux(String.class)。
  • 適用場景:適用于大多數常見的請求處理場景,特別是當你不需要手動處理響應狀態碼時。

exchange()

  • 用途:exchange() 方法提供了更底層的控制,允許你手動處理響應,包括響應狀態碼和響應頭。
  • 手動錯誤處理:exchange() 不會自動處理 HTTP 錯誤狀態碼,你需要手動檢查響應狀態碼并進行相應的處理。
  • 返回值:返回 ClientResponse 對象,你可以從中提取響應狀態碼、響應頭和響應體。
  • 適用場景:適用于需要手動處理響應狀態碼或響應頭的復雜場景。

示例對比

retrieve()

public Mono<JSONObject> get(String q1) {return webClient.get().uri(uriBuilder -> uriBuilder.path("/get").queryParam("q1", q1).build()).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(JSONObject.class);
}

exchange()

public Mono<JSONObject> get(String q1) {return webClient.get().uri(uriBuilder -> uriBuilder.path("/get").queryParam("q1", q1).build()).accept(MediaType.APPLICATION_JSON).exchangeToMono(response -> {if (response.statusCode().is2xxSuccessful()) {return response.bodyToMono(JSONObject.class);} else {return Mono.error(new RuntimeException("Request failed with status code: " + response.statusCode()));}});
}

4. 使用示例

4.1 基本請求操作

package com.coderjia.boot3webflux.service;import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;/*** @author CoderJia* @create 2024/12/3 下午 10:22* @Description**/
@Service
public class ApiService {@Resourceprivate WebClient webClient;// GET請求public Mono<JSONObject> get(String q1) {return webClient.get().uri(uriBuilder -> uriBuilder.path("/get").queryParam("q1", q1).build()).accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(JSONObject.class);}// POST請求public Mono<JSONObject> post(JSONObject body) {return webClient.post().uri("/post").bodyValue(body).retrieve().bodyToMono(JSONObject.class);}// PUT請求public Mono<JSONObject> put(String q1, JSONObject JSONObject) {return webClient.put().uri(uriBuilder -> uriBuilder.path("/put").queryParam("q1", q1).build()).bodyValue(JSONObject).retrieve().bodyToMono(JSONObject.class);}// DELETE請求public Mono<JSONObject> delete(String q1) {return webClient.delete().uri(uriBuilder -> uriBuilder.path("/delete").queryParam("q1", q1).build()).retrieve().bodyToMono(JSONObject.class);}
}

效果展示

get

post

put

delete

4.2 處理復雜響應

@Service
public class ApiService {// 獲取列表數據public Flux<JSONObject> getAllUsers() {return webClient.get().uri("/users").retrieve().bodyToFlux(JSONObject.class);}// 處理錯誤響應public Mono<JSONObject> getUserWithErrorHandling(Long id) {return webClient.get().uri("/users/{id}", id).retrieve().onStatus(HttpStatusCode::is4xxClientError, clientResponse -> Mono.error(new RuntimeException("客戶端錯誤"))).onStatus(HttpStatusCode::is5xxServerError, clientResponse -> Mono.error(new RuntimeException("服務器錯誤"))).bodyToMono(JSONObject.class);}// 使用exchange()方法獲取完整響應public Mono<ResponseEntity<JSONObject>> getUserWithFullResponse(Long id) {return webClient.get().uri("/users/{id}", id).accept(MediaType.APPLICATION_JSON).exchange().flatMap(response -> response.toEntity(JSONObject.class));}
}

4.3 高級用法

@Service
public class ApiService {// 帶請求頭的請求public Mono<JSONObject> getUserWithHeaders(Long id, String token) {return webClient.get().uri("/users/{id}", id).header("Authorization", "Bearer " + token).retrieve().bodyToMono(JSONObject.class);}// 帶查詢參數的請求public Flux<JSONObject> searchUsers(String name, int age) {return webClient.get().uri(uriBuilder -> uriBuilder.path("/users/search").queryParam("name", name).queryParam("age", age).build()).retrieve().bodyToFlux(JSONObject.class);}// 文件上傳public Mono<String> uploadFile(FilePart filePart) {return webClient.post().uri("/upload").contentType(MediaType.MULTIPART_FORM_DATA).body(BodyInserters.fromMultipartData("file", filePart)).retrieve().bodyToMono(String.class);}
}

5. 最佳實踐

  1. 合理使用響應式類型

    • 使用 Mono 用于單個對象
    • 使用 Flux 用于集合數據
    • 注意背壓處理
  2. 錯誤處理

     public Mono<JSONObject> getUserWithRetry(Long id) {return webClient.get().uri("/users/{id}", id).retrieve().bodyToMono(JSONObject.class).retryWhen(Retry.backoff(3, Duration.ofSeconds(1))).timeout(Duration.ofSeconds(5)).onErrorResume(TimeoutException.class,e -> Mono.error(new RuntimeException("請求超時")));}
    
  3. 資源管理

    • 使用連接池
    • 設置適當的超時時間
    • 實現優雅關閉

6. 注意事項

  1. WebClient 是非阻塞的,需要注意響應式編程的特性
  2. 合理配置連接池和超時參數
  3. 在生產環境中實現適當的錯誤處理和重試機制
  4. 注意內存使用,特別是處理大量數據時

7. 與RestTemplate對比

特性

WebClient

RestTemplate

編程模型

響應式、非阻塞

同步、阻塞

性能

更好

一般

資源利用

更高效

一般

學習曲線

較陡

平緩

適用場景

高并發、響應式系統

簡單應用、傳統系統

8. 總結

WebClient 作為 Spring 推薦的新一代 HTTP 客戶端,提供了強大的響應式編程能力和更好的性能。雖然相比 RestTemplate 有一定的學習曲線,但在現代微服務架構中,其帶來的好處遠超過學習成本。建議在新項目中優先考慮使用WebClient,特別是在需要處理高并發請求的場景下。

參考資料

  • Spring WebClient官方文檔
  • Spring Boot官方文檔
  • Project Reactor文檔

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66704.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66704.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66704.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.Net Core微服務入門全紀錄(二)——Consul-服務注冊與發現(上)

系列文章目錄 1、.Net Core微服務入門系列&#xff08;一&#xff09;——項目搭建 2、.Net Core微服務入門全紀錄&#xff08;二&#xff09;——Consul-服務注冊與發現&#xff08;上&#xff09; 3、.Net Core微服務入門全紀錄&#xff08;三&#xff09;——Consul-服務注…

Spark Streaming的核心功能及其示例PySpark代碼

Spark Streaming是Apache Spark中用于實時流數據處理的模塊。以下是一些常見功能的實用PySpark代碼示例&#xff1a; 基礎流處理&#xff1a;從TCP套接字讀取數據并統計單詞數量 from pyspark import SparkContext from pyspark.streaming import StreamingContext# 創建Spar…

深度學習系列75:sql大模型工具vanna

1. 概述 vanna是一個可以將自然語言轉為sql的工具。簡單的demo如下&#xff1a; !pip install vanna import vanna from vanna.remote import VannaDefault vn VannaDefault(modelchinook, api_keyvanna.get_api_key(my-emailexample.com)) vn.connect_to_sqlite(https://va…

【線性代數】列主元法求矩陣的逆

列主元方法是一種用于求解矩陣逆的數值方法&#xff0c;特別適用于在計算機上實現。其基本思想是通過高斯消元法將矩陣轉換為上三角矩陣&#xff0c;然后通過回代求解矩陣的逆。以下是列主元方法求解矩陣 A A A 的逆的步驟&#xff1a; [精確算法] 列主元高斯消元法 步驟 1&am…

[0242-06].第06節:SpringBoot對SpringMVC的自動配置

SpringBoot學習大綱 一、基于SpringBoot搭建Web工程&#xff1a; 1.1.編碼實現步驟&#xff1a; a.創建SpringBoot項目 b.選中依賴&#xff1a;選中我們所需要的模塊 1.2.SSM中的WEB開發配置與SpringBoot中WEB開發自動配置對比&#xff1a; a.SSM中的WEB開發&#xff1a; 1…

【21】Word:德國旅游業務?

目錄 題目 NO1.2.3 NO4 NO5.6 NO7 NO8.9.10.11 題目 NO1.2.3 F12&#xff1a;另存為布局→頁面設置→頁邊距&#xff1a;上下左右選中“德國主要城市”→開始→字體對話框→字體/字號→文本效果&#xff1a;段落對話框→對齊方式/字符間距/段落間距 NO4 布局→表對話框…

什么是軟件架構

什么是軟件架構 程序員說&#xff0c;軟件架構是要決定編寫哪些C程序或OO類、使用哪些庫和框架 程序經理說&#xff0c;軟件架構就是模塊的劃分和接口的定義 系統分析員說&#xff0c;軟件架構就是為業務領域對象的關系建模 配置管理員說&#xff0c;軟件架構就是開發出來的…

1/20賽后總結

1/20賽后總結 T1『討論區管理員』的旅行 - BBC編程訓練營 算法&#xff1a;IDA* 分數&#xff1a;0 damn it! Ac_code走丟了~~&#xff08;主要是沒有寫出來&#xff09;~~ T2華強買瓜 - BBC編程訓練營 算法&#xff1a;雙向DFS或者DFS剪枝 分數&#xff1a;0 Ac_code…

大數據與AI驅動的商業查詢平臺:企業市場拓展的變革引擎?

在競爭白熱化的商業環境里&#xff0c;企業對準確市場信息的高效獲取能力&#xff0c;直接關系到業務拓展的成敗。商業查詢平臺借助大數據和人工智能技術&#xff0c;為企業提供精準客戶篩選、市場拓展分析以及風險評估服務&#xff0c;正逐漸成為企業市場開拓的得力助手。本文…

redis 各個模式的安裝

一、Redis單機安裝 1、安裝gcc依賴 Redis是C語言編寫的&#xff0c;編譯需要GCC。 Redis6.x.x版本支持了多線程&#xff0c;需要gcc的版本大于4.9&#xff0c;但是CentOS7的默認版本是4.8.5。 升級gcc版本&#xff1a; yum -y install centos-release-scl yum -y install d…

TiDB 的優勢與劣勢

TiDB 的優勢與劣勢 TiDB 作為一款新興的分布式數據庫&#xff0c;在業界逐漸嶄露頭角。它兼具傳統關系型數據庫的特性&#xff0c;又充分利用分布式架構的優勢。那么&#xff0c;TiDB 究竟有怎樣的優缺點呢&#xff1f;今天我們來聊聊 TiDB 的優勢與劣勢&#xff0c;幫你全面了…

藍橋杯算法日常|c\c++常用競賽函數總結備用

一、字符處理相關函數 大小寫判斷函數 islower和isupper&#xff1a;是C標準庫中的字符分類函數&#xff0c;用于檢查一個字符是否為小寫字母或大寫字母&#xff0c;需包含頭文件cctype.h&#xff08;也可用萬能頭文件包含&#xff09;。返回布爾類型值。例如&#xff1a; #…

微服務知識——4大主流微服務架構方案

文章目錄 1、微服務聚合模式2、微服務共享模式3、微服務代理模式4、微服務異步消息模式 微服務是大型架構的必經之路&#xff0c;也是大廠重點考察對象&#xff0c;下面我就重點詳解4大主流微服務架構方案。 1、微服務聚合模式 微服務聚合設計模式&#xff0c;解決了如何從多個…

【HTML+CSS】使用HTML與后端技術連接數據庫

目錄 一、概述 1.1 HTML前端 1.2 后端技術 1.3 數據庫 二、HTML表單示例 三、PHP后端示例 3.1 連接數據庫 3.2 接收數據并插入數據庫 四、安全性 4.1 防止SQL注入 4.2 數據驗證與清洗 五、優化 5.1 索引優化 5.2 查詢優化 六、現代Web開發中的最佳實踐 6.1 使用…

T-SQL語言的數據庫編程

T-SQL語言的數據庫編程 1. 引言 在信息化迅速發展的今天&#xff0c;數據庫已經成為數據管理和使用的重要工具。其中&#xff0c;T-SQL&#xff08;Transact-SQL&#xff09;作為微軟SQL Server的擴展SQL語言&#xff0c;不僅用于數據查詢和管理&#xff0c;還能夠進行復雜的…

通信協議—WebSocket

一、WebSocket編程概念 1.1 什么是WebSocket WebSocket 是一種全雙工通信協議&#xff0c;允許在客戶端&#xff08;通常是瀏覽器&#xff09;和服務器之間建立持久連接&#xff0c;以實現實時的雙向通信。它是 HTML5 標準的一部分&#xff0c;相比傳統的 HTTP 請求&#xff…

cadence筆記--畫PMU6050原理圖和封裝

簡介 本文主要介紹使用Cadence自己畫一個PMU6050的原理圖PCB的實際用例&#xff0c;Cadence使用的是24.1版本。 原理圖 首先獲取PMU6050引腳參數&#xff0c;使用立創商城查詢PMU6050型號&#xff0c;點擊數據手冊如下圖所示&#xff1a; 如下圖所示&#xff0c;左邊是原理圖&…

CSS3 3D 轉換介紹

CSS3 中的 3D 轉換提供了一種在二維屏幕上呈現三維效果的方式&#xff0c;主要包括translate3d、rotate3d、scale3d等轉換函數&#xff0c;下面來詳細介紹&#xff1a; 1. 3D 轉換的基本概念 坐標系 在 CSS3 的 3D 空間中&#xff0c;使用的是右手坐標系。X 軸是水平方向&…

Text2SQL 智能報表方案介紹

0 背景 Text2SQL智能報表方案旨在通過自然語言處理&#xff08;NLP&#xff09;技術&#xff0c;使用戶能夠以自然語言的形式提出問題&#xff0c;并自動生成相應的SQL查詢&#xff0c;從而獲取所需的數據報表&#xff0c;用戶可根據得到結果展示分析從而為結論提供支撐&#…

FFmpeg音視頻采集

文章目錄 音視頻采集音頻采集獲取設備信息錄制麥克風錄制聲卡 視頻采集攝像機畫面采集 音視頻采集 DirectShow&#xff08;簡稱DShow&#xff09;是一個Windows平臺上的流媒體框架&#xff0c;提供了高質量的多媒體流采集和回放功能&#xff0c;它支持多種多樣的媒體文件格式&…