Java如何使用 HttpClientUtils 發起 HTTP 請求
- 一、前言
- 1.HttpClientUtils 類概覽
- 2.解析 HttpClientUtils 類
- 3.使用 HttpClientUtils 類
一、前言
在現代的軟件開發中,經常需要與遠程服務器進行通信,例如獲取數據或發送數據。Apache HttpClient 是一個流行的 Java HTTP 客戶端庫,能夠簡化 HTTP 請求的發起和響應處理。本文將介紹如何使用自定義的 HttpClientUtils
類來利用 Apache HttpClient 發起 POST 請求,并且管理連接池以優化性能。
1.HttpClientUtils 類概覽
public class HttpClientUtils {// 靜態常量和變量聲明private static final int MAX_TOTAL_CONN = 600;private static final int MAX_CONN_PER_HOST = 300;private static final int SOCKET_TIMEOUT = 5000;private static final int CONNECTION_TIMEOUT = 200;private static final int CONNECTION_MANAGER_TIMEOUT = 100;private static CloseableHttpClient httpclient;private static PoolingHttpClientConnectionManager connMrg;private static String encoding = StandardCharsets.UTF_8.name();private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);private static final ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(2);// 靜態代碼塊,用于初始化 HttpClient 和連接管理器,并設置 JVM 退出時關閉 HttpClientstatic {init();destroyByJvmExit();}// 初始化連接管理器和 HttpClientprivate static void init() {connMrg = new PoolingHttpClientConnectionManager();connMrg.setMaxTotal(MAX_TOTAL_CONN);connMrg.setDefaultMaxPerRoute(MAX_CONN_PER_HOST);httpclient = HttpClients.custom().setConnectionManager(connMrg).setDefaultRequestConfig(HttpClientUtils.defaultRequestConfig()).build();// 定時任務,定期清理過期和空閑連接scheduledService.scheduleAtFixedRate(() -> {connMrg.closeExpiredConnections();connMrg.closeIdleConnections(CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);}, 0, CONNECTION_MANAGER_TIMEOUT, TimeUnit.MILLISECONDS);}// JVM 退出時關閉 HttpClientprivate static void destroyByJvmExit() {Runtime.getRuntime().addShutdownHook(new Thread(() -> {try {httpclient.close();} catch (IOException e) {log.error("Error closing HttpClient: {}", e.getMessage());}}));}// 創建 HttpClientContextprivate static HttpClientContext createContext() {return HttpClientContext.create();}// 創建默認的 RequestConfigprivate static RequestConfig defaultRequestConfig() {return RequestConfig.custom().setConnectTimeout(CONNECTION_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).setConnectionRequestTimeout(CONNECTION_MANAGER_TIMEOUT).build();}// 發起帶參數的 POST 表單請求,返回字符串結果public static String postWithParamsForString(String url, List<NameValuePair> params) {HttpPost httpPost = new HttpPost();try {URI uri = new URIBuilder(url).build();httpPost.setURI(uri);httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));return executeRequest(httpPost);} catch (URISyntaxException | IOException e) {log.error("Error executing POST request: {}", e.getMessage());} finally {httpPost.releaseConnection();}return null;}// 發起 GET 請求,返回字符串結果public static String get(String url, List<NameValuePair> params) {HttpGet httpGet = new HttpGet();try {URI uri = new URIBuilder(url).setParameters(params).build();httpGet.setURI(uri);return executeRequest(httpGet);} catch (URISyntaxException | IOException e) {log.error("HTTP GET request failed", e);} finally {httpGet.releaseConnection();}return null;}// 發起 Post 請求,返回字符串結果public static String post(String url, List<NameValuePair> params) {HttpPost httpPost = new HttpPost();try {httpPost.setURI(new URI(url));httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));return executeRequest(httpPost);} catch (URISyntaxException | IOException e) {log.error("HTTP POST request failed", e);} finally {httpPost.releaseConnection();}return null;}// 執行 HTTP 請求并處理響應private static String executeRequest(HttpUriRequest request) throws IOException {try (CloseableHttpResponse response = httpclient.execute(request, createContext())) {int statusCode = response.getStatusLine().getStatusCode();if (statusCode == HttpStatus.SC_OK) {HttpEntity entity = response.getEntity();if (entity != null) {return EntityUtils.toString(entity, encoding);} else {log.warn("Empty response entity");}} else {log.error("HTTP request failed with status code: {}", statusCode);}} catch (IOException e) {log.error("HTTP request execution failed: {}", e.getMessage());throw e;}return null;}
}
2.解析 HttpClientUtils 類
-
靜態常量和變量:
- 定義了最大連接數、連接超時時間、Socket 超時時間等常量和變量。
-
初始化和銷毀:
- 在靜態代碼塊中初始化了
HttpClient
和連接管理器PoolingHttpClientConnectionManager
。 - 使用
ScheduledExecutorService
定期清理過期和空閑連接。 - 在
destroyByJvmExit
方法中,注冊了一個 JVM 退出鉤子,確保在 JVM 關閉時關閉HttpClient
。
- 在靜態代碼塊中初始化了
-
HTTP 請求方法:
postWithParamsForString
方法用于執行帶參數的 POST 請求。- 使用
HttpPost
構建請求,設置 URL 和請求參數,最終調用executeRequest
方法執行請求。
-
執行請求和處理響應:
executeRequest
方法接收HttpUriRequest
,執行 HTTP 請求并處理響應。- 檢查響應的狀態碼,如果是 200(OK),則讀取響應實體并將其轉換為字符串返回。
- 使用日志記錄錯誤和警告信息,確保代碼的健壯性和可靠性。
3.使用 HttpClientUtils 類
使用 HttpClientUtils
類可以簡化 HTTP 請求的編寫和管理,具體步驟如下:
public class Main {public static void main(String[] args) {List<NameValuePair> params = new ArrayList<>();params.add(new BasicNameValuePair("param1", "value1"));params.add(new BasicNameValuePair("param2", "value2"));String response = HttpClientUtils.postWithParamsForString("http://example.com/api", params);if (response != null) {System.out.println("Response: " + response);} else {System.err.println("Failed to execute POST request");}}
}
通過以上學習,你現在應該了解如何使用 HttpClientUtils
類來管理 HTTP 客戶端和發起請求。這種方式可以幫助你在 Java 應用中更高效地處理 HTTP 通信,同時通過連接池和定期清理機制提升性能和穩定性。