首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Apache HttpClient 4.x 發送 JSON POST 請求工具類封裝與最佳實踐

     編輯:Java 相關知識

Apache HttpClient 是 Java 呼叫 HTTP API 的經典選擇。本文提供生產級 RequestUtil 封裝,涵蓋 JSON POST 請求建構、連線池管理、超時配置、回應處理與例外轉換,並說明 HttpClient 4.5+ 至 5.x 遷移要點與現代化替代方案。

核心工具類實作(HttpClient 4.5.x)


package com.example.http;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class RequestUtil {
    
    // 共用客戶端(線程安全、連線池預設 200 路徑、20 路徑/路由)
    private static final CloseableHttpClient HTTP_CLIENT = HttpClients.custom()
        .setDefaultRequestConfig(RequestConfig.custom()
            .setConnectTimeout(5000)      // 連線超時 5s
            .setSocketTimeout(15000)      // 讀取超時 15s
            .setConnectionRequestTimeout(1000) // 從池取連線超時 1s
            .build())
        .evictIdleConnections(30, TimeUnit.SECONDS) // 定期清理閒置連線
        .build();
    
    /**
     * 發送 JSON POST 請求
     * @param url 目標 URL
     * @param json JSON 字串(可為 null/空,發送空物件 {})
     * @return 回應本文字串
     * @throws IOException 網路/IO 異常
     */
    public static String postJson(String url, String json) throws IOException {
        HttpPost post = buildJsonPost(url, json);
        try (CloseableHttpResponse response = HTTP_CLIENT.execute(post)) {
            return parseResponse(response);
        }
    }
    
    private static HttpPost buildJsonPost(String url, String json) {
        HttpPost post = new HttpPost(url);
        post.setHeader("Accept", "application/json");
        post.setHeader("Content-Type", "application/json; charset=UTF-8");
        
        String payload = StringUtils.isBlank(json) ? "{}" : json;
        post.setEntity(new StringEntity(payload, StandardCharsets.UTF_8));
        return post;
    }
    
    private static String parseResponse(CloseableHttpResponse response) throws IOException {
        HttpEntity entity = response.getEntity();
        if (entity == null) return "{}";
        try {
            return EntityUtils.toString(entity, StandardCharsets.UTF_8);
        } finally {
            EntityUtils.consumeQuietly(entity); // 確保釋放連線回池
        }
    }
    
    // 應用關閉時呼叫釋放資源
    public static void shutdown() throws IOException {
        HTTP_CLIENT.close();
    }
}

關鍵設計解析

  1. 單例客戶端:CloseableHttpClient 線程安全、內建連線池,**全應用僅建立一次**,避免頻繁建立/關閉導致連線耗盡與 TIME_WAIT 堆積。
  2. 三層超時控制:
    • ConnectTimeout:TCP 三向交握超時。
    • SocketTimeout:資料讀取無回應超時(業務邏輯處理時間)。
    • ConnectionRequestTimeout:從連線池取得可用連線超時(高併發防護)。
  3. 資源釋放鐵律:EntityUtils.consumeQuietly(entity) 或 try-with-resources 確保連線歸還池中,否則連線洩漏導致後續請求卡死。
  4. 編碼顯式指定:StandardCharsets.UTF_8 避免平台預設編碼差異導致中文亂碼。

進階擴展:重試、熔斷、監控


// 1. 重試機制(針對冪等請求)
HttpClientBuilder.create()
    .setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)) // 重試 3 次
    .build();

// 2. 熔斷整合(Resilience4j + HttpClient)
// 需自訂 HttpRequestInterceptor 搭配 CircuitBreaker

// 3. 監控指標(Micrometer)
// 攔截器記錄:請求耗時、狀態碼分布、錯誤率、連線池使用率

HttpClient 5.x 遷移要點(當前主流版本)

4.x 類別5.x 對應備註
CloseableHttpClientCloseableHttpClient套件變更:org.apache.http.client → org.apache.hc.client5.http
HttpPostHttpPost建構方式相同
StringEntityStringEntity套件變更
EntityUtilsEntityUtils方法簽名微調
RequestConfigRequestConfigBuilder 模式統一
HttpClients.custom()HttpClients.custom()配置 API 大同小異

Maven 依賴變更:


<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3.1</version>
</dependency>

現代化替代方案建議

  1. Spring RestTemplate / WebClient:Spring 生態專案首選,整合攔截器、訊息轉換器、負載均衡(Ribbon/Spring Cloud LoadBalancer)。
  2. OkHttp 4.x:Square 出品,HTTP/2 原生支援、連線池效能優異、API 簡潔、支援同步/非同步呼叫。
  3. Java 11+ HttpClient:JDK 內建 java.net.http.HttpClient,支援 HTTP/2、WebSocket、CompletableFuture 非同步、零依賴。

常見問題排查表

錯誤現象可能原因排查方向
Connection refused目標服務未啟動/防火牆/端口錯誤telnet/curl 驗證網路連通性
Read timed outSocketTimeout 過短/下游處理慢調整 SocketTimeout、檢查下游效能
Pool exhausted連線洩漏/池大小不足/併發過高檢查 EntityUtils.consume、調大 MaxTotal/MaxPerRoute
SSLHandshakeException憑證不信任/主機名驗證失敗信任憑證鏈、或設定信任所有(僅測試)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved