gembin

          OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

          HBase, Hadoop, ZooKeeper, Cassandra

          Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

          There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

          About Me

           

          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 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。

          • 實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
          • 支持自動轉向
          • 支持 HTTPS 協議
          • 支持代理服務器等

          下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。



          HttpClient 基本功能的使用

          GET 方法

          使用 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;
          import java.io.IOException;
          import org.apache.commons.httpclient.*;
          import org.apache.commons.httpclient.methods.GetMethod;
          import org.apache.commons.httpclient.params.HttpMethodParams;
          public class GetSample{
          public static void main(String[] args) {
          //構造HttpClient的實例
          HttpClient httpClient = new HttpClient();
          //創建GET方法的實例
          GetMethod getMethod = new GetMethod("http://www.ibm.com");
          //使用系統提供的默認的恢復策略
          getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
          new DefaultHttpMethodRetryHandler());
          try {
          //執行getMethod
          int statusCode = httpClient.executeMethod(getMethod);
          if (statusCode != HttpStatus.SC_OK) {
          System.err.println("Method failed: "
          + getMethod.getStatusLine());
          }
          //讀取內容
          byte[] responseBody = getMethod.getResponseBody();
          //處理內容
          System.out.println(new String(responseBody));
          } catch (HttpException e) {
          //發生致命的異常,可能是協議不對或者返回的內容有問題
          System.out.println("Please check your provided http address!");
          e.printStackTrace();
          } catch (IOException e) {
          //發生網絡異常
          e.printStackTrace();
          } finally {
          //釋放連接
          getMethod.releaseConnection();
          }
          }
          }

          POST方法

          根據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";
          PostMethod postMethod = new PostMethod(url);
          // 填入各個表單域的值
          NameValuePair[] data = { new NameValuePair("id", "youUserName"),
          new NameValuePair("passwd", "yourPwd") };
          // 將表單的值放入postMethod中
          postMethod.setRequestBody(data);
          // 執行postMethod
          int statusCode = httpClient.executeMethod(postMethod);
          // HttpClient對于要求接受后繼服務的請求,象POST和PUT等不能自動處理轉發
          // 301或者302
          if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
          statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
          // 從頭中取出轉向的地址
          Header locationHeader = postMethod.getResponseHeader("location");
          String location = null;
          if (locationHeader != null) {
          location = locationHeader.getValue();
          System.out.println("The page was redirected to:" + location);
          } else {
          System.err.println("Location field value is null.");
          }
          return;
          }
          HTTPClient的主頁是http://jakarta.apache.org/commons/httpclient/,你可以在這里得到關于HttpClient更加詳細的信息

          posted on 2008-03-26 18:31 gembin 閱讀(789) 評論(0)  編輯  收藏 所屬分類: JavaSE

          導航

          統計

          常用鏈接

          留言簿(6)

          隨筆分類(440)

          隨筆檔案(378)

          文章檔案(6)

          新聞檔案(1)

          相冊

          收藏夾(9)

          Adobe

          Android

          AS3

          Blog-Links

          Build

          Design Pattern

          Eclipse

          Favorite Links

          Flickr

          Game Dev

          HBase

          Identity Management

          IT resources

          JEE

          Language

          OpenID

          OSGi

          SOA

          Version Control

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          free counters
          主站蜘蛛池模板: 常德市| 资阳市| 平舆县| 漯河市| 崇仁县| 鸡东县| 石台县| 延庆县| 肃南| 新乡县| 孟村| 霞浦县| 芦山县| 平湖市| 宣汉县| 大余县| 措美县| 仪征市| 巫山县| 莱州市| 华阴市| 图片| 太和县| 赣州市| 宜君县| 舟曲县| 称多县| 沧源| 伊吾县| 陈巴尔虎旗| 临武县| 章丘市| 微山县| 常熟市| 永泰县| 达日县| 湘乡市| 高安市| 南郑县| 万安县| 合山市|