一、GET 方法
    使用 HttpClient 需要以下 6 個步驟:
    1. 創(chuàng)建 HttpClient 的實例
    2. 創(chuàng)建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構(gòu)造函數(shù)中傳入待連接的地址
    3. 調(diào)用第一步中創(chuàng)建好的實例的 execute 方法來執(zhí)行第二步中創(chuàng)建好的 method 實例
    4. 讀 response
    5. 釋放連接。無論執(zhí)行方法是否成功,都必須釋放連接
    6. 對得到后的內(nèi)容進(jìn)行處理

    根據(jù)以上步驟,我們來編寫用GET方法取得某網(wǎng)頁內(nèi)容的代碼。
    1、大部分情況下 HttpClient 默認(rèn)的構(gòu)造函數(shù)已經(jīng)足夠使用。
 
       HttpClient httpClient = new HttpClient();

    2、創(chuàng)建GET方法的實例。
      在GET方法的構(gòu)造函數(shù)中傳入待連接的地址即可。用GetMethod將會自動處理轉(zhuǎn)發(fā)過程,如果想要把自動處理轉(zhuǎn)發(fā)過程去掉的話,可以調(diào)用方法setFollowRedirects(false)。
     
      GetMethod getMethod = new GetMethod("http://www.ibm.com/");

    3、調(diào)用 httpClient 的 executeMethod 方法來執(zhí)行 getMethod。
      由于是執(zhí)行在網(wǎng)絡(luò)上的程序,在運行executeMethod方法的時候,需要處理兩個異常,分別是HttpException和IOException。引起第一種異常的原因主要可能是在構(gòu)造getMethod的時候傳入的協(xié)議不對,比如將"http"寫成了"htp",或者服務(wù)器端返回的內(nèi)容不正常等,并且該異常發(fā)生是不可恢復(fù)的;第二種異常一般是由于網(wǎng)絡(luò)原因引起的異常,對于這種異常(IOException),HttpClient會根據(jù)你指定的恢復(fù)策略自動試著重新執(zhí)行executeMethod方法。HttpClient的恢復(fù) 策略可以自定義(通過實現(xiàn)接口HttpMethodRetryHandler來實現(xiàn))。通過httpClient的方法setParameter設(shè)置你實現(xiàn)的恢復(fù)策略,本例中使用的是系統(tǒng)提供的默認(rèn)恢復(fù)策略,該策略在碰到第二類異常的時候?qū)⒆詣又卦?次。executeMethod返回值是一個整數(shù),表示了執(zhí)行該方法后服務(wù)器返回的狀態(tài)碼,該狀態(tài)碼能表示出該方法執(zhí)行是否成功、需要認(rèn)證或者頁面發(fā)生了跳轉(zhuǎn)(默認(rèn)狀態(tài)下GetMethod的實例是自動處理跳轉(zhuǎn)的)等。

     //設(shè)置成了默認(rèn)的恢復(fù)策略,在發(fā)生異常時候?qū)⒆詣又卦?次,在這里你也可以設(shè)置成自定義的恢復(fù)策略
     getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                                              
new DefaultHttpMethodRetryHandler());
     //執(zhí)行g(shù)etMethod
     int statusCode = client.executeMethod(getMethod);
     if (statusCode != HttpStatus.SC_OK) {
          System.err.println(
"Method failed: " + getMethod.getStatusLine());
     }

    4、在返回的狀態(tài)碼正確后,即可取得內(nèi)容。
      取得目標(biāo)地址的內(nèi)容有三種方法:
      Ⅰ、getResponseBody,該方法返回的是目標(biāo)的二進(jìn)制的byte流;
      Ⅱ、getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據(jù)系統(tǒng)默認(rèn)的編碼方式,所以返回的String值可能編碼類型有誤;
      Ⅲ、getResponseBodyAsStream,這個方法對于目標(biāo)地址中有大量數(shù)據(jù)需要傳輸是最佳的。
      在這里我們使用了最簡單的 getResponseBody方法。

       byte[] responseBody = method.getResponseBody();

    5、釋放連接。
       無論執(zhí)行方法是否成功,都必須釋放連接。
     
       method.releaseConnection();

    6、處理內(nèi)容。
      在這一步中根據(jù)你的需要處理內(nèi)容,本例中只是簡單的將內(nèi)容打印到控制臺。
     
       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         //構(gòu)造HttpClient的實例
 9         HttpClient httpClient = new HttpClient();
10         //創(chuàng)建GET方法的實例
11         GetMethod getMethod = new GetMethod("http://www.ibm.com");
12         //使用系統(tǒng)提供的默認(rèn)的恢復(fù)策略
13         getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
14                                                  new DefaultHttpMethodRetryHandler());
15         try {
16           //執(zhí)行g(shù)etMethod
17           int statusCode = httpClient.executeMethod(getMethod);
18           if (statusCode != HttpStatus.SC_OK) {
19               System.err.println("Method failed: "
20                                         + getMethod.getStatusLine());
21           }
22            //讀取內(nèi)容
23            byte[] responseBody = getMethod.getResponseBody();
24            //處理內(nèi)容
25            System.out.println(new String(responseBody));
26         } catch (HttpException e) {
27            //發(fā)生致命的異常,可能是協(xié)議不對或者返回的內(nèi)容有問題
28            System.out.println("Please check your provided http address!");
29            e.printStackTrace();
30         } catch (IOException e) {
31            //發(fā)生網(wǎng)絡(luò)異常
32            e.printStackTrace();
33         } finally {
34            //釋放連接
35            getMethod.releaseConnection();
36         }
37       }
38    }

二、POST方法
    POST 方法用來向目的服務(wù)器發(fā)出請求,要求它接受被附在請求后的實體,并把它當(dāng)作請求隊列(Request-Line)中請求URI所指定資源的附加新子項。
    調(diào)用 HttpClient 中的 PostMethod 與 GetMethod 類似,除了設(shè)置 PostMethod 的實例與 GetMethod 有些不同之外,剩下的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方。
    構(gòu)造 PostMethod 之前的步驟都相同,與 GetMethod 一樣,構(gòu)造 PostMethod 也需要一個URI參數(shù),在創(chuàng)建了PostMethod的實例之后,需要給method實例填充表單的值,一般的登錄表單中需要有兩個域,第一個是用戶名,第二個是密碼。表單中的域用類 NameValuePair 來表示,該類的構(gòu)造函數(shù)第一個參數(shù)是表單域名名稱,第二參數(shù)是該域的值;將表單所有的值設(shè)置到 PostMethod 中用方法 setRequestBody。如果登錄成功后會轉(zhuǎn)向另外一個頁面,HttpClient對于要求接受后繼服務(wù)的請求,比如POST和PUT,不支持自動轉(zhuǎn)發(fā),因此需要自己對頁面轉(zhuǎn)向做處理。
    代碼如下:
 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  // 執(zhí)行postMethod
 9  int statusCode = httpClient.executeMethod(postMethod);
10  // HttpClient對于要求接受后繼服務(wù)的請求,象POST和PUT等不能自動處理轉(zhuǎn)發(fā)
11  // 301或者302
12  if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
13                       statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
14      // 從頭中取出轉(zhuǎn)向的地址
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  }