【SpringBoot整合系列】HttpClient遠程訪問的示例

前言

  1. 使用Apache的HttpClient庫,添加Apache HttpClient的依賴。
  2. 工具類的封裝。通常,工具類需要處理GET、POST請求,可能還有其他方法如PUT、DELETE。需要設計一個工具類,提供靜態方法,可以發送請求,并處理響應。同時要考慮連接超時、讀取超時的設置,以及請求頭的配置,比如Content-Type、User-Agent等
  3. 然后,需要處理請求參數的封裝。對于GET請求,參數通常是查詢字符串;對于POST,可能需要表單參數或者JSON body。因此,工具類可能需要支持不同的參數類型,比如使用Map<String, String>來傳遞表單參數,或者直接傳入一個JSON字符串作為請求體。
  4. 異常處理也是關鍵。網絡請求可能會拋出IOException等異常,工具類需要捕獲這些異常,并可能轉換成自定義異常,或者返回null,或者記錄日志,具體取決于設計選擇。需要靈活處理錯誤,所以可能需要將異常拋出讓調用者處理,或者在工具類內部處理并返回錯誤信息。
  5. 另外,響應處理方面,需要將HttpEntity轉換為字符串,并正確關閉連接,確保資源釋放。使用EntityUtils.toString時要注意字符編碼,通常使用UTF-8。同時,需要關閉HttpResponse和HttpClient,或者使用try-with-resources來自動管理資源,但Apache HttpClient 4.x版本的response關閉可能需要注意,需要確保正確關閉流。

注意事項

  1. 工具類可能包含sendGet和sendPost方法。例如,sendGet接收URL和參數Map,構造帶查詢參數的URL;sendPost接收URL和可能的表單參數或JSON body,并設置合適的Content-Type。此外,可能需要設置請求頭,比如設置JSON的Content-Type為application/json。

  2. 工具類的設計要盡量簡潔,可配置。比如,可以允許自定義連接超時時間、讀取超時時間,或者設置默認的請求頭。可能使用HttpClient的配置,比如RequestConfig來設置超時參數。

  3. 可能的陷阱包括:未正確處理參數編碼,比如在GET請求中,參數需要進行URL編碼;在POST發送表單時,需要將參數轉換為UrlEncodedFormEntity;發送JSON時,要使用StringEntity,并設置Content-Type為application/json。

  4. 需要注意線程安全,HttpClient通常建議重用實例,所以工具類中可能使用靜態的CloseableHttpClient實例,并通過靜態代碼塊初始化,確保線程安全。但需確認是否每次請求需要新的實例,或者可以共享。根據Apache HttpClient文檔,建議重復使用同一個實例,因為它是線程安全的,并且管理連接池更高效。所以工具類中可以創建一個單例的HttpClient實例。

  5. 另外,工具類可能需要處理不同的Content-Type,比如POST發送JSON時,需要設置對應的頭信息,并處理不同的數據體。因此,sendPost可能需要參數來指定發送的數據類型,或者通過方法重載來處理不同情況。

    • 例如,提供sendPostForm用于發送表單,sendPostJson用于發送JSON。或者,在方法中傳遞一個contentType參數,并根據類型構造不同的HttpEntity。

    • 或者,更靈活的方式是讓調用者傳入一個HttpEntity對象,這樣工具類更通用,但使用起來可能不夠方便。所以需要在易用性和靈活性之間權衡。

    • 這里工具類可以提供兩個方法:一個處理表單參數(Map類型),另一個處理JSON字符串。

整體思路

  1. 引入Apache HttpClient依賴。

  2. 創建HttpClientUtil類,封裝創建HttpClient實例的方法,配置超時等參數。

  3. 實現sendGet方法,處理參數拼接和編碼。

  4. 實現sendPost方法,處理表單或JSON數據的提交。

  5. 處理響應,將結果轉換為字符串。

  6. 異常處理,關閉資源。

  7. 提供使用示例。

代碼示例

Maven依賴

<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>

HttpClientUtil

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class HttpClientUtil {// 超時配置(單位:毫秒)private static final int CONNECT_TIMEOUT = 5000;private static final int SOCKET_TIMEOUT = 5000;// 創建可復用的HttpClient實例private static final CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build()).build();/*** 發送GET請求* @param url 請求地址* @param params 請求參數* @return 響應內容*/public static String sendGet(String url, Map<String, String> params) {HttpGet httpGet = new HttpGet(buildUri(url, params));try (CloseableHttpResponse response = httpClient.execute(httpGet)) {return handleResponse(response);} catch (IOException e) {throw new RuntimeException("GET請求失敗", e);}}/*** 發送POST表單請求(application/x-www-form-urlencoded)* @param url 請求地址* @param formData 表單數據* @return 響應內容*/public static String sendPostForm(String url, Map<String, String> formData) {HttpPost httpPost = new HttpPost(url);List<NameValuePair> params = new ArrayList<>();formData.forEach((k, v) -> params.add(new BasicNameValuePair(k, v)));httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));return executePost(httpPost);}/*** 發送POST JSON請求(application/json)* @param url 請求地址* @param json JSON字符串* @return 響應內容*/public static String sendPostJson(String url, String json) {HttpPost httpPost = new HttpPost(url);StringEntity entity = new StringEntity(json, "UTF-8");entity.setContentType("application/json");httpPost.setEntity(entity);return executePost(httpPost);}private static String executePost(HttpPost httpPost) {try (CloseableHttpResponse response = httpClient.execute(httpPost)) {return handleResponse(response);} catch (IOException e) {throw new RuntimeException("POST請求失敗", e);}}private static URI buildUri(String url, Map<String, String> params) {try {URIBuilder uriBuilder = new URIBuilder(url);if (params != null) {params.forEach(uriBuilder::addParameter);}return uriBuilder.build();} catch (URISyntaxException e) {throw new IllegalArgumentException("URL格式錯誤", e);}}private static String handleResponse(CloseableHttpResponse response) throws IOException {int statusCode = response.getStatusLine().getStatusCode();if (statusCode != 200) {throw new RuntimeException("HTTP響應異常,狀態碼:" + statusCode);}HttpEntity entity = response.getEntity();return entity != null ? EntityUtils.toString(entity, "UTF-8") : null;}
}

使用示例

import java.util.HashMap;
import java.util.Map;public class Example {public static void main(String[] args) {// GET請求示例String getUrl = "https://api.example.com/data";Map<String, String> params = new HashMap<>();params.put("key1", "value1");params.put("key2", "value2");String getResponse = HttpClientUtil.sendGet(getUrl, params);System.out.println("GET響應內容:" + getResponse);// POST表單示例String postFormUrl = "https://api.example.com/submit";Map<String, String> formData = new HashMap<>();formData.put("username", "testuser");formData.put("password", "testpass");String postFormResponse = HttpClientUtil.sendPostForm(postFormUrl, formData);System.out.println("POST表單響應:" + postFormResponse);// POST JSON示例String postJsonUrl = "https://api.example.com/submit-json";String jsonPayload = "{\"name\":\"John\", \"age\":30}";String postJsonResponse = HttpClientUtil.sendPostJson(postJsonUrl, jsonPayload);System.out.println("POST JSON響應:" + postJsonResponse);}
}

總結

工具類特點:

  • 線程安全: 使用單個共享的HttpClient實例,復用連接池資源
  • 超時配置: 統一設置5秒連接/讀取超時
  • 編碼處理: 統一使用UTF-8編碼
  • 異常處理: 將檢查異常轉換為運行時異常,簡化調用
  • 支持多種請求:
    • GET請求(帶查詢參數)
    • POST表單(application/x-www-form-urlencoded)
    • POST JSON(application/json)
  • 響應處理: 自動驗證狀態碼并轉換響應內容

注意事項:

  • 根據實際情況調整超時時間配置
  • 生產環境建議添加日志記錄
  • 需要處理其他狀態碼(如3xx重定向)時可擴展handleResponse方法
  • 如需添加自定義請求頭,可擴展方法參數
  • 注意及時釋放資源,使用try-with-resources自動關閉響應

可根據實際需求進一步擴展支持:

  • 文件上傳
  • HTTPS配置
  • 代理設置
  • 請求重試機制
  • 更完善的異常處理等

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

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

相關文章

Git操作整體流程

文章目錄 1.Git創建個人倉庫2、Git全局配置3、Git本地管理4. Git本地管理常用命令匯總5、使用Git命令將項目提交到遠程碼云管理6.使用IDEA進行管理7、Idea里面的終端8、關于提交總結 1.Git創建個人倉庫 打開https://gitee.com/&#xff0c;登錄個人賬號&#xff0c;右上角加號…

MySQL MHA 部署全攻略:從零搭建高可用數據庫架構

文章目錄 1.MHA介紹2.MHA組件介紹3.集群規劃4.服務器初始化5.MySQL集群部署5.1 安裝MySQL集群5.2 配置一主兩從5.3 測試MySQL主從5.4 賦予MHA用戶連接權限 6.安裝MHA環境6.1 安裝MHA Node6.2 安裝MHA Manager 7.配置MHA環境8.MySQL MHA高可用集群測試8.1 通過VIP連接MySQL8.2模…

如何查看java的字節碼文件?javap?能用IDEA嗎?

編譯指令&#xff1a; javac YourProject.java 查看字節碼文件的指令&#xff1a; javap -c -l YourProject.class 不添加-c指令就不會顯示字節碼文件&#xff1a; 不添加 -l 就不會顯示源代碼和字節碼文件的對應關系&#xff1a; 添加-l之后多出來這些&#xff1a; IDEA不太…

1、Window Android 13模擬器 將編譯的映像文件導入Android Studio

1、環境準備 編譯環境&#xff1a;Ubuntu-18.04.5編譯版本&#xff1a;android13-release下載地址&#xff1a;清華大學開源軟件鏡像站AOSP # 下載repo # 同步代碼&#xff1a;repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android13-r…

JUC并發—9.并發安全集合三

大綱 1.并發安全的數組列表CopyOnWriteArrayList 2.并發安全的鏈表隊列ConcurrentLinkedQueue 3.并發編程中的阻塞隊列概述 4.JUC的各種阻塞隊列介紹 5.LinkedBlockingQueue的具體實現原理 6.基于兩個隊列實現的集群同步機制 1.并發安全的數組列表CopyOnWriteArrayList …

報錯:Cannot read properties of null (reading ‘ce‘)解決方法

背景 工作項目中要做右鍵菜單打開趨勢圖彈窗的需求&#xff0c;這個彈窗使用了vue-resizable的第三方插件&#xff0c;這個插件的主要作用是把彈窗設置為可拖拽的效果。這個用vue-resizable做的彈窗已經做好了&#xff0c;在別的項目中能夠正常的運行。但是我把它拿過來放在新…

Ubuntu 下 nginx-1.24.0 源碼分析 - ngx_process_options

ngx_process_options 聲明在 src\core\nginx.c static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); 定義在 src\core\nginx.c static ngx_int_t ngx_process_options(ngx_cycle_t *cycle) {u_char *p;size_t len;if (ngx_prefix) {len ngx_strlen(ngx_prefix);p …

數據結構系列二:包裝類+泛型

包裝類泛型 一、包裝類&#xff08;1&#xff09;基本數據類型和對應的包裝類&#xff08;2&#xff09;裝箱和拆箱 二、泛型&#xff08;1&#xff09;什么是泛型&#xff08;2&#xff09;引出泛型&#xff08;3&#xff09;語法&#xff08;4&#xff09;泛型類的使用1.語法…

量子計算驅動的金融衍生品定價革命:突破傳統蒙特卡洛模擬的性能邊界

引言&#xff1a;金融計算的算力困局 某國際投行采用128量子位處理器對亞洲期權組合定價時&#xff0c;其量子振幅估計算法在2.7秒內完成傳統GPU集群需要68小時的計算任務。在蒙特卡洛路徑模擬實驗中&#xff0c;量子隨機游走算法將10,000維衍生品的價格收斂速度提升4個數量級…

Spring容器初始化擴展點:ApplicationContextInitializer

目錄 一、什么是ApplicationContextInitializer&#xff1f; 1、核心作用2、適用場景 二、ApplicationContextInitializer的使用方式 1、實現ApplicationContextInitializer接口2、注冊初始化器 三、ApplicationContextInitializer的執行時機四、實際應用案例 1、動態設置環境…

hive—常用的函數整理

1、size(split(...))函數用于計算分割后字符串數組的長度 實例1&#xff09;&#xff1a;由客戶編號列表計算客戶編號個數 --數據準備 with tmp_test01 as ( select tag074445270 tag_id,202501busi_mon , 012399931003,012399931000 index_val union all select tag07444527…

vue3 采用xlsx庫實現本地上傳excel文件,前端解析為Json數據

需求&#xff1a;本地上傳excel 文件&#xff0c;但需要對excel 文件的內容進行解析&#xff0c;然后展示出來 1. 安裝依賴 首先&#xff0c;確保安裝了 xlsx 庫&#xff1a; bash復制 npm install xlsx 2. 創建 Vue 組件 創建一個 Vue 組件&#xff08;如 ExcelUpload.v…

若依框架實現動態失效時間JWT Token的實踐指南

一、功能需求背景 在前后端分離架構中&#xff0c;JWT&#xff08;JSON Web Token&#xff09;作為無狀態認證方案被廣泛使用。若依&#xff08;RuoYi&#xff09;框架的TokenService默認采用固定失效時間策略&#xff0c;但在實際開發中常需要根據業務場景動態調整Token有效期…

C++ 設計模式-策略模式

支付策略 #include <iostream> #include <memory> #include <unordered_map> #include <vector> #include <ctime>// 基礎策略接口 class PaymentStrategy { public:virtual ~PaymentStrategy() default;virtual std::string name() const 0;…

國產編輯器EverEdit - 如何在EverEdit中管理工程?

1 工程管理 1.1 應用場景 用戶創建工程后&#xff0c;會涉及到工程的管理 &#xff0c;比如&#xff1a;打開工程、關閉工程等 1.2 使用方法 1.2.1 打開工程 單擊主菜單工程 -> 打開工程&#xff0c;會彈出打開對話框&#xff0c;用戶在對話框中選擇需要打開的工程文件即…

MYSQL-數據庫-DDL-DML-DQL-DCL-基礎學習

MySql概念&#xff1a; 建立在關系模型基礎上&#xff0c;有多張相互連接的二維表組成的數據庫 SQL通用語法&#xff1a; 1.SQL語句可以單行或多行書寫&#xff0c;以分號結尾 2.SQL語句可以使用空格/縮進來增強語句的可讀性 3.MySQL數據庫的SQL語句不區分大小寫&#xff0c;關…

SpringBoot核心框架之AOP詳解

SpringBoot核心框架之AOP詳解 一、AOP基礎 1.1 AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面編程&#xff0c;面向方面編程&#xff09;&#xff0c;其實就是面向特定方法編程。 場景&#xff1a;項目部分功能運行較慢&#xff0c;定位執行耗時…

【RK3588嵌入式圖形編程】-SDL2-構建模塊化UI

構建模塊化UI 文章目錄 構建模塊化UI1、概述2、創建UI管理器3、嵌套組件4、繼承5、多態子組件6、總結在本文中,將介紹如何使用C++和SDL創建一個靈活且可擴展的UI系統,重點關注組件層次結構和多態性。 1、概述 在前面的文章中,我們介紹了應用程序循環和事件循環,這為我們的…

第四屆圖像、信號處理與模式識別國際學術會議(ISPP 2025)

重要信息 會議官網&#xff1a;www.icispp.com 會議時間&#xff1a;2025年3月28-30日 會議地點&#xff1a;南京 簡介 由河海大學和江蘇大學聯合主辦的第四屆圖像、信號處理與模式識別國際學術會議&#xff08;ISPP 2025) 將于2025年3月28日-30日在中國南京舉行。會議主…

低代碼與開發框架的一些整合[2]

1.分析的項目資源說明 經過近期的的不斷分析與運行對比&#xff0c;最終把注意力集中在了以下幾個框架&#xff1a; 01.dibootdiboot.diboot: 寫的更少, 性能更好 -> 為開發人員打造的低代碼開發平臺。Mybatis-plus關聯查詢&#xff0c;關聯無SQL&#xff0c;性能高10倍&a…