Apache HttpClient 是 Java 傳統專案常用的 HTTP 客戶端庫(注意:HttpClient 5.x API 已大幅變更,本文針對 4.5.x 版本)。本文示範 GET/POST 基本用法、表單提交、重導向處理、Cookie 策略與自訂 UTF-8 POST 類別。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.14</version>
</dependency>
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import java.io.*;
public class HttpClientDemo {
public static void main(String[] args) {
HttpClient client = new HttpClient();
client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
// ---------- GET 請求 ----------
GetMethod get = new GetMethod("https://httpbin.org/get");
try {
int status = client.executeMethod(get);
if (status == HttpStatus.SC_OK) {
System.out.println("GET 回應:" + get.getResponseBodyAsString());
}
} catch (IOException e) { e.printStackTrace(); }
finally { get.releaseConnection(); }
// ---------- POST 表單提交 ----------
PostMethod post = new UTF8PostMethod("https://httpbin.org/post");
NameValuePair[] data = {
new NameValuePair("username", "test_user"),
new NameValuePair("password", "secret123")
};
post.setRequestBody(data);
post.setRequestHeader("Referer", "https://httpbin.org/");
try {
int status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
System.out.println("POST 回應:" + post.getResponseBodyAsString());
} else if (status == HttpStatus.SC_MOVED_TEMPORARILY) {
// 處理 302 重導向
Header loc = post.getResponseHeader("Location");
if (loc != null) {
PostMethod redirectPost = new UTF8PostMethod(loc.getValue());
redirectPost.setRequestBody(data);
redirectPost.setRequestHeader("Referer", "https://httpbin.org/post");
client.executeMethod(redirectPost);
System.out.println("重導向後回應:" + redirectPost.getResponseBodyAsString());
redirectPost.releaseConnection();
}
}
} catch (IOException e) { e.printStackTrace(); }
finally { post.releaseConnection(); }
}
// 自訂 UTF-8 POST 類別(解決 4.x 預設 ISO-8859-1 編碼問題)
static class UTF8PostMethod extends PostMethod {
public UTF8PostMethod(String url) { super(url); }
@Override public String getRequestCharSet() { return "UTF-8"; }
}
}
| 項目 | 說明 |
|---|---|
| 重試機制 | DefaultHttpMethodRetryHandler 可設定重試次數與是否重試冪等請求 |
| Cookie 策略 | CookiePolicy.BROWSER_COMPATIBILITY 模擬瀏覽器行為,自動儲存/送出 Cookie |
| 編碼處理 | 繼承 PostMethod 覆寫 getRequestCharSet() 回傳 UTF-8 |
| 資源釋放 | 務必在 finally 呼叫 releaseConnection(),否則連線洩漏 |
| 回應讀取 | 使用 getResponseBodyAsStream() 配合 BufferedReader 逐行讀取,避免大回應 OOM |
新專案建議直接使用 org.apache.httpcomponents.client5:httpclient5,API 為 HttpClients.createDefault()、ClassicHttpRequest、ClassicHttpResponse,支援非阻塞 IO 與 HTTP/2。