HTTP 協定是現在 Internet 上使用得最多、最重要的協定,越來越多的 Java 應用程序需要直接通過 HTTP 協定來訪問網路資源。 雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協定的基本功能,但是對於大部分應用程序來說,JDK 類別庫本身提供的功能還不夠豐富和靈活。 HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效能、最新、功能豐富的支持 HTTP 協定的client端開發工具,並且它支持 HTTP 協定最新的版本和建議。 HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。 HttpClient 項目非常活躍,使用的人還是非常多的。目前 HttpClient 正式版本是 3.1。
HttpClient 功能介紹
以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。
1. 實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
2. 支持自動轉向
3. 支持 HTTPS 協議
4. 支持代理服務器
下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。
HttpClient 可以在http://hc.apache.org/downloads.cgi下載
HttpClient用到了logging,你可以從這個地址http://commons.apache.org/downloads/download_logging.cgi下載到 common-logging,從下載後的壓縮包中取出 commons-logging.jar 加到 CLASSPATH 中
HttpClient用到了codec,你可以從這個地址http://commons.apache.org/downloads/download_codec.cgi 下載到最新的 common-codec,從下載後的壓縮包中取出 commons-codec-1.x.jar 加到 CLASSPATH 中
Get Method:
import java.io.IOException; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; public class HttpGet { private static String url = "http://www.apache.org/"; // 目標網址. public static void main(String[] args) { // 建立HttpClient實體. HttpClient client = new HttpClient(); // 建立GetMethod實體, 並指派網址, GetMethod會自動處理該網轉址動作, 如果不想自動轉址請呼叫 setFollowRedirects(false). GetMethod method = new GetMethod(url); // 這段代碼用意為連接不到時自動重新��試三次. method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); try { // 返回狀態值. int statusCode = client.executeMethod(method); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + method.getStatusLine()); } // 取得回傳資訊. byte[] responseBody = method.getResponseBody(); System.out.println(new String(responseBody)); } catch (HttpException httpexc) { System.err.println("Fatal protocol violation: " + httpexc.getMessage()); httpexc.printStackTrace(); } catch (IOException ioexc) { System.err.println("Fatal transport error: " + ioexc.getMessage()); ioexc.printStackTrace(); } finally { // ** 無論如何都必須釋放連接. method.releaseConnection(); } } }
由於是執行在網路上的程序,運行executeMethod方法時,需要處理兩個異常,分別是HttpException和IOException。 第一種異常的原因主要可能是在建立GetMethod的時候輸入網址錯誤,比如不小心將"http"寫成"htp",或者遠端返回的資訊內容不正常等,並且該異常發生是不可恢復的。
第二種異常一般是由於網路原因引起的異常,對於這種異常 (IOException),HttpClient會根據你指定的恢復策略自動試著重新執行executeMethod方法。
HttpClient的恢復策略可以自定義(通過實現接口HttpMethodRetryHandler來實現)。通過httpClient的方法setParameter設置你實現的恢復策略,這裡使用的是系統提供的預設恢復方式,該方式在碰到第二類異常的時候將自動重試3次。
executeMethod返回值是一個整數,表示了執行該方法後服務器返回的狀態碼,該狀態碼能表示出該方法執行是否成功、需要認證或者頁面轉址(預設狀態下GetMethod是自動處理轉址)等。
POST Method:
import java.io.IOException; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; public class HttpPost { private static String url = "http://www.apache.org/"; // 目標網址. public static void main(String[] args) { // 建立HttpClient實體. HttpClient client = new HttpClient(); // 建立PostMethod實體, 並指派網址 PostMethod post = new PostMethod(url); // 建立NameValuePair陣列�儲欲傳送的資料, 對照為 (名稱, 內容) NameValuePair[] data = { new NameValuePair("Name", "Sam Wang"), new NameValuePair("Passwd", "Test1234") }; // 將NameValuePair陣列設置到請求內容中 post.setRequestBody(data); try { // 返回狀態值. int statusCode = client.executeMethod(post); if (statusCode != HttpStatus.SC_OK) { System.err.println("Method failed: " + post.getStatusLine()); } // 取得回傳資訊. byte[] responseBody = post.getResponseBody(); System.out.println(new String(responseBody)); } catch (HttpException httpexc) { System.err.println("Fatal protocol violation: " + httpexc.getMessage()); httpexc.printStackTrace(); } catch (IOException ioexc) { System.err.println("Fatal transport error: " + ioexc.getMessage()); ioexc.printStackTrace(); } finally { // ** 無論如何都必須釋放連接. post.releaseConnection(); } } }
PostMethod運作重點大致上和GetMethod相同, 唯一不同的是傳送變數必須用NameValuePair[]陣列儲存, 再設置到requestBody中。
how to upload file by httpclient?
回覆刪除org.apache.commons.httpclient.params.HttpMethodParams
回覆刪除請問 這行我一直無法 import 進去 ‥
是因為 HttpClient 3.1 沒有安裝好嗎?
有可能是版本更新,可能要查一下API中有無那個Class,如果沒有就要Google一下解決方案
回覆刪除真不好意思 在尋問一下 ‥ 我檢查過 HttpClient 3.1 的 api裡是有
回覆刪除org.apache.commons.httpclient.params.HttpMethodParams 的 class
但是 我用 eclipse 來開發時出現以下的錯誤!
Access restriction: The type HttpMethodParams is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\ext\commons-httpclient-3.1.jar
感謝您細心地教學分享,讓我終於解決了 import org.apache.commons.httpclient 錯誤的問題...
回覆刪除原來是我一直下錯檔案,我一直在下 HttpClient 4.0.1 (GA) 這個的4.0.1的版本,卻不知道是要下最下面的 Commons HttpClient 3.1 (legacy) 的 3.1 的版本,
感謝您的分享