HttpClient簡介
HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。本文首先介紹 HTTPClient,然后根據作者實際工作經驗給出了一些常見問題的解決方法。
HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能,但是對于大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項目非常活躍,使用的人還是非常多的。目前 HttpClient 版本是在 2005.10.11 發布的 3.0 RC4 。
以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。
- 實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
- 支持自動轉向
- 支持 HTTPS 協議
- 支持代理服務器等
下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。
- HttpClient 可以在http://jakarta.apache.org/commons/httpclient/downloads.html下載
- HttpClient 用到了 Apache Jakarta common 下的子項目 logging,你可以從這個地址http://jakarta.apache.org/site/downloads/downloads_commons-logging.cgi下載到 common logging,從下載后的壓縮包中取出 commons-logging.jar 加到 CLASSPATH 中
- HttpClient 用到了 Apache Jakarta common 下的子項目 codec,你可以從這個地址http://jakarta.apache.org/site/downloads/downloads_commons-codec.cgi 下載到最新的 common codec,從下載后的壓縮包中取出 commons-codec-1.x.jar 加到 CLASSPATH 中
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
4. 讀 response
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
6. 對得到后的內容進行處理
根據以上步驟,我們來編寫用GET方法來取得某網頁內容的代碼。
- 大部分情況下 HttpClient 默認的構造函數已經足夠使用。
HttpClient httpClient = new HttpClient();
- 創建GET方法的實例。在GET方法的構造函數中傳入待連接的地址即可。用GetMethod將會自動處理轉發過程,如果想要把自動處理轉發過程去掉的話,可以調用方法setFollowRedirects(false)。
GetMethod getMethod = new GetMethod("http://www.ibm.com/");
- 調用實例httpClient的
executeMethod方法來執行getMethod。由于是執行在網絡上的程序,在運行executeMethod方法的時候,需要處理兩個異常,
分別是HttpException和IOException。引起第一種異常的原因主要可能是在構造getMethod的時候傳入的協議不對,比如不小心
將"http"寫成"htp",或者服務器端返回的內容不正常等,并且該異常發生是不可恢復的;第二種異常一般是由于網絡原因引起的異常,對于這種異常
(IOException),HttpClient會根據你指定的恢復策略自動試著重新執行executeMethod方法。HttpClient的恢復
策略可以自定義(通過實現接口HttpMethodRetryHandler來實現)。通過httpClient的方法setParameter設置你實
現的恢復策略,本文中使用的是系統提供的默認恢復策略,該策略在碰到第二類異常的時候將自動重試3次。executeMethod返回值是一個整數,表示
了執行該方法后服務器返回的狀態碼,該狀態碼能表示出該方法執行是否成功、需要認證或者頁面發生了跳轉(默認狀態下GetMethod的實例是自動處理跳
轉的)等。
//設置成了默認的恢復策略,在發生異常時候將自動重試3次,在這里你也可以設置成自定義的恢復策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
//執行getMethod
int statusCode = client.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + getMethod.getStatusLine());
}
-
在返回的狀態碼正確后,即可取得內容。取得目標地址的內容有三種方法:第一種,getResponseBody,該方法返回的是目標的二進制的byte
流;第二種,getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據系
統默認的編碼方式,所以返回的String值可能編碼類型有誤,在本文的"字符編碼"部分中將對此做詳細介紹;第三種,
getResponseBodyAsStream,這個方法對于目標地址中有大量數據需要傳輸是最佳的。在這里我們使用了最簡單的
getResponseBody方法。
byte[] responseBody = method.getResponseBody();
- 釋放連接。無論執行方法是否成功,都必須釋放連接。
method.releaseConnection();
- 處理內容。在這一步中根據你的需要處理內容,在例子中只是簡單的將內容打印到控制臺。
System.out.println(new String(responseBody));
下面是程序的完整代碼,這些代碼也可在附件中的test.GetSample中找到。
package test; |
根據RFC2616,對POST的解釋如下:POST方法用來向目的服務器發出請求,要求它接受被附在請求后的實體,并把它當作請求隊列(Request-Line)中請求URI所指定資源的附加新子項。POST被設計成用統一的方法實現下列功能:
- 對現有資源的注釋(Annotation of existing resources)
- 向電子公告欄、新聞組,郵件列表或類似討論組發送消息
- 提交數據塊,如將表單的結果提交給數據處理過程
- 通過附加操作來擴展數據庫
調 用HttpClient中的PostMethod與GetMethod類似,除了設置PostMethod的實例與GetMethod有些不同之外,剩下 的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方,并以登錄清華大學BBS為例子進行說明。
構 造PostMethod之前的步驟都相同,與GetMethod一樣,構造PostMethod也需要一個URI參數,在本例中,登錄的地址是http: //www.newsmth.net/bbslogin2.php。在創建了PostMethod的實例之后,需要給method實例填充表單的值,在 BBS的登錄表單中需要有兩個域,第一個是用戶名(域名叫id),第二個是密碼(域名叫passwd)。表單中的域用類NameValuePair來表 示,該類的構造函數第一個參數是域名,第二參數是該域的值;將表單所有的值設置到PostMethod中用方法setRequestBody。另外由于 BBS登錄成功后會轉向另外一個頁面,但是HttpClient對于要求接受后繼服務的請求,比如POST和PUT,不支持自動轉發,因此需要自己對頁面 轉向做處理。具體的頁面轉向處理請參見下面的"自動轉向"部分。代碼如下:
String url = "http://www.newsmth.net/bbslogin2.php"; |
posted on 2008-03-26 18:31 gembin 閱讀(789) 評論(0) 編輯 收藏 所屬分類: JavaSE