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

HttpClient 4.x 發送 GET/POST 請求完整實戰代碼(含 Header、參數、響應處理)

     編輯:Java 綜合教學

前言

Apache HttpClient 是 Java 領域最成熟的 HTTP 客戶端庫,支援 HTTP/1.1、連接池、認證、攔截器等企業級特性。本文基於 HttpClient 4.5+,提供可直接複製運行的 GET/POST 完整示例,涵蓋 Header 設置、表單參數、JSON 參數、超時配置、響應解析等高頻場景。

一、Maven 依賴

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>
<!-- JSON 處理可選 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.4</version>
</dependency>

二、通用工具類封裝(推薦生產使用)

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.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.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtil {

    private static final CloseableHttpClient HTTP_CLIENT = HttpClients.custom()
            .setDefaultRequestConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)   // 連接超時 5s
                    .setSocketTimeout(10000)   // 讀取超時 10s
                    .setConnectionRequestTimeout(1000)
                    .build())
            .build();

    /** 關閉客戶端(應用關閉時調用) */
    public static void close() throws IOException {
        HTTP_CLIENT.close();
    }

    /**
     * GET 請求
     * @param url 請求地址
     * @param headers 請求頭 Map
     * @param params URL 參數 Map(自動拼接到 URL)
     * @return 響應字符串
     */
    public static String doGet(String url, Map headers, Map params) throws IOException {
        // 1. 拼接參數
        if (params != null && !params.isEmpty()) {
            StringBuilder sb = new StringBuilder(url.contains("?") ? "&" : "?");
            params.forEach((k, v) -> sb.append(k).append('=').append(v).append('&'));
            sb.deleteCharAt(sb.length() - 1);
            url += sb;
        }

        // 2. 創建請求
        HttpGet httpGet = new HttpGet(url);
        if (headers != null) {
            headers.forEach(httpGet::setHeader);
        }

        // 3. 執行並解析響應
        return execute(httpGet);
    }

    /**
     * POST 表單請求 (application/x-www-form-urlencoded)
     */
    public static String doPostForm(String url, Map headers, Map formParams) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        if (headers != null) {
            headers.forEach(httpPost::setHeader);
        }

        if (formParams != null && !formParams.isEmpty()) {
            List pairs = new ArrayList<>();
            formParams.forEach((k, v) -> pairs.add(new BasicNameValuePair(k, v)));
            httpPost.setEntity(new UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8));
        }

        return execute(httpPost);
    }

    /**
     * POST JSON 請求 (application/json)
     */
    public static String doPostJson(String url, Map headers, String jsonBody) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
        if (headers != null) {
            headers.forEach(httpPost::setHeader);
        }
        if (jsonBody != null) {
            httpPost.setEntity(new org.apache.http.entity.StringEntity(jsonBody, StandardCharsets.UTF_8));
        }
        return execute(httpPost);
    }

    /** 統一執行與響應處理 */
    private static String execute(org.apache.http.client.methods.HttpUriRequest request) throws IOException {
        try (CloseableHttpResponse response = HTTP_CLIENT.execute(request)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, StandardCharsets.UTF_8);
            }
            return "";
        }
    }
}

三、業務調用示例

1. GET 請求(攜帶 Authorization Header)

public String getDailySummary(String accessToken) throws IOException {
    Map headers = Map.of("Authorization", "Bearer " + accessToken);
    return HttpClientUtil.doGet("https://api.microsofthealth.net/v1/me/Summaries/Daily", headers, null);
}

2. POST 表單請求(OAuth2 獲取 Token)

public String getOAuthToken(String clientId, String redirectUri, String clientSecret, String code) throws IOException {
    Map form = Map.of(
        "client_id", clientId,
        "redirect_uri", redirectUri,
        "client_secret", clientSecret,
        "code", code,
        "grant_type", "authorization_code"
    );
    Map headers = Map.of("Content-Type", "application/x-www-form-urlencoded");
    return HttpClientUtil.doPostForm("https://login.live.com/oauth20_token.srf", headers, form);
}

3. POST JSON 請求(現代 API 常用)

// 需 Jackson 依賴
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(Map.of("userId", 123, "action", "login"));

Map headers = Map.of("Authorization", "Bearer token_xxx");
String resp = HttpClientUtil.doPostJson("https://api.example.com/action", headers, json);

四、進階配置提示

需求配置方式
連接池複用HttpClients.custom().setMaxConnTotal(200).setMaxConnPerRoute(50)
HTTPS 忽略證書驗證(測試環境)實現 TrustStrategy 返回 true,構建 SSLContext 並 .setSSLContext()
自動重試.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true))
攔截器(日誌/簽名).addInterceptorLast(new HttpRequestInterceptor() {...})
多部分/文件上傳使用 MultipartEntityBuilder 構建 HttpEntity

五、避坑指南

  • 必須關閉響應:使用 try-with-resources 自動釋放連接回池,否則連接泄漏導致池耗盡。
  • 編碼統一 UTF-8:UrlEncodedFormEntity(pairs, StandardCharsets.UTF_8)、EntityUtils.toString(entity, StandardCharsets.UTF_8)。
  • 超時設置:連接超時、讀取超時、請求超時三者分開配置,防止線程無限掛起。
  • 單例客戶端:CloseableHttpClient 線程安全,全局僅需一個實例,應用關閉時統一 close()。
  • HttpClient 5.x:新項目建議直接使用 5.x(org.apache.httpcomponents.client5:httpclient5),API 更現代、支援 HTTP/2、異步非阻塞。

六、總結

HttpClient 4.x 雖屬經典版本,但在大量存量項目中仍廣泛使用。掌握 工具類封裝、Header/參數/Body 多樣化構建、統一異常與資源處理,即可應對 90% 以上的 HTTP 交互場景。新項目優先考慮 HttpClient 5.x 或 WebClient (Spring WebFlux) 獲得更現代的體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved