一、GET 方法
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
4. 讀 response
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
6. 對得到后的內容進行處理
根據以上步驟,我們來編寫用GET方法取得某網頁內容的代碼。
1、大部分情況下 HttpClient 默認的構造函數已經足夠使用。
HttpClient httpClient = new HttpClient();
2、創建GET方法的實例。
在GET方法的構造函數中傳入待連接的地址即可。用GetMethod將會自動處理轉發過程,如果想要把自動處理轉發過程去掉的話,可以調用方法setFollowRedirects(false)。
GetMethod getMethod = new GetMethod("http://www.ibm.com/");
3、調用 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());
}
4、在返回的狀態碼正確后,即可取得內容。
取得目標地址的內容有三種方法:
Ⅰ、getResponseBody,該方法返回的是目標的二進制的byte流;
Ⅱ、getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據系統默認的編碼方式,所以返回的String值可能編碼類型有誤;
Ⅲ、getResponseBodyAsStream,這個方法對于目標地址中有大量數據需要傳輸是最佳的。
在這里我們使用了最簡單的 getResponseBody方法。
byte[] responseBody = method.getResponseBody();
5、釋放連接。
無論執行方法是否成功,都必須釋放連接。
method.releaseConnection();
6、處理內容。
在這一步中根據你的需要處理內容,本例中只是簡單的將內容打印到控制臺。
System.out.println(new String(responseBody));
下面是程序的完整代碼:
1 package test;
2 import java.io.IOException;
3 import org.apache.commons.httpclient.*;
4 import org.apache.commons.httpclient.methods.GetMethod;
5 import org.apache.commons.httpclient.params.HttpMethodParams;
6 public class GetSample{
7 public static void main(String[] args) {
8 //構造HttpClient的實例
9 HttpClient httpClient = new HttpClient();
10 //創建GET方法的實例
11 GetMethod getMethod = new GetMethod("http://www.ibm.com");
12 //使用系統提供的默認的恢復策略
13 getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
14 new DefaultHttpMethodRetryHandler());
15 try {
16 //執行getMethod
17 int statusCode = httpClient.executeMethod(getMethod);
18 if (statusCode != HttpStatus.SC_OK) {
19 System.err.println("Method failed: "
20 + getMethod.getStatusLine());
21 }
22 //讀取內容
23 byte[] responseBody = getMethod.getResponseBody();
24 //處理內容
25 System.out.println(new String(responseBody));
26 } catch (HttpException e) {
27 //發生致命的異常,可能是協議不對或者返回的內容有問題
28 System.out.println("Please check your provided http address!");
29 e.printStackTrace();
30 } catch (IOException e) {
31 //發生網絡異常
32 e.printStackTrace();
33 } finally {
34 //釋放連接
35 getMethod.releaseConnection();
36 }
37 }
38 }
二、POST方法
POST 方法用來向目的服務器發出請求,要求它接受被附在請求后的實體,并把它當作請求隊列(Request-Line)中請求URI所指定資源的附加新子項。
調用 HttpClient 中的 PostMethod 與 GetMethod 類似,除了設置 PostMethod 的實例與 GetMethod 有些不同之外,剩下的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方。
構造 PostMethod 之前的步驟都相同,與 GetMethod 一樣,構造 PostMethod 也需要一個URI參數,在創建了PostMethod的實例之后,需要給method實例填充表單的值,一般的登錄表單中需要有兩個域,第一個是用戶名,第二個是密碼。表單中的域用類 NameValuePair 來表示,該類的構造函數第一個參數是表單域名名稱,第二參數是該域的值;將表單所有的值設置到 PostMethod 中用方法 setRequestBody。如果登錄成功后會轉向另外一個頁面,HttpClient對于要求接受后繼服務的請求,比如POST和PUT,不支持自動轉發,因此需要自己對頁面轉向做處理。
代碼如下:
1 String url = "http://www.test.com/login.jsp";
2 PostMethod postMethod = new PostMethod(url);
3 // 填入各個表單域的值
4 NameValuePair[] data = { new NameValuePair("id", "youUserName"),
5 new NameValuePair("passwd", "yourPwd") };
6 // 將表單的值放入postMethod中
7 postMethod.setRequestBody(data);
8 // 執行postMethod
9 int statusCode = httpClient.executeMethod(postMethod);
10 // HttpClient對于要求接受后繼服務的請求,象POST和PUT等不能自動處理轉發
11 // 301或者302
12 if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
13 statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
14 // 從頭中取出轉向的地址
15 Header locationHeader = postMethod.getResponseHeader("location");
16 String location = null;
17 if (locationHeader != null) {
18 location = locationHeader.getValue();
19 System.out.println("The page was redirected to:" + location);
20 } else {
21 System.err.println("Location field value is null.");
22 }
23 return;
24 }