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 下的子項(xiàng)目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。本文首先介紹 HTTPClient,然后根據(jù)作者實(shí)際工作經(jīng)驗(yàn)給出了一些常見問題的解決方法。

          HTTP 協(xié)議可能是現(xiàn)在 Internet 上使用得最多、最重要的協(xié)議了,越來越多的 Java 應(yīng)用程序需要直接通過 HTTP 協(xié)議來訪問網(wǎng)絡(luò)資源。雖然在 JDK 的 java.net 包中已經(jīng)提供了訪問 HTTP 協(xié)議的基本功能,但是對于大部分應(yīng)用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項(xiàng)目,用來提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。HttpClient 已經(jīng)應(yīng)用在很多的項(xiàng)目中,比如 Apache Jakarta 上很著名的另外兩個(gè)開源項(xiàng)目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應(yīng)用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項(xiàng)目非常活躍,使用的人還是非常多的。目前 HttpClient 版本是在 2005.10.11 發(fā)布的 3.0 RC4 。


          HttpClient 功能介紹

          以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細(xì)的功能可以參見 HttpClient 的主頁。

          • 實(shí)現(xiàn)了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
          • 支持自動轉(zhuǎn)向
          • 支持 HTTPS 協(xié)議
          • 支持代理服務(wù)器等

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



          HttpClient 基本功能的使用

          GET 方法

          使用 HttpClient 需要以下 6 個(gè)步驟:

          1. 創(chuàng)建 HttpClient 的實(shí)例

          2. 創(chuàng)建某種連接方法的實(shí)例,在這里是 GetMethod。在 GetMethod 的構(gòu)造函數(shù)中傳入待連接的地址

          3. 調(diào)用第一步中創(chuàng)建好的實(shí)例的 execute 方法來執(zhí)行第二步中創(chuàng)建好的 method 實(shí)例

          4. 讀 response

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

          6. 對得到后的內(nèi)容進(jìn)行處理

          根據(jù)以上步驟,我們來編寫用GET方法來取得某網(wǎng)頁內(nèi)容的代碼。

          • 大部分情況下 HttpClient 默認(rèn)的構(gòu)造函數(shù)已經(jīng)足夠使用。
            HttpClient httpClient = new HttpClient();

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

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

          • 在返回的狀態(tài)碼正確后,即可取得內(nèi)容。取得目標(biāo)地址的內(nèi)容有三種方法:第一種,getResponseBody,該方法返回的是目標(biāo)的二進(jìn)制的byte 流;第二種,getResponseBodyAsString,這個(gè)方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據(jù)系 統(tǒng)默認(rèn)的編碼方式,所以返回的String值可能編碼類型有誤,在本文的"字符編碼"部分中將對此做詳細(xì)介紹;第三種, getResponseBodyAsStream,這個(gè)方法對于目標(biāo)地址中有大量數(shù)據(jù)需要傳輸是最佳的。在這里我們使用了最簡單的 getResponseBody方法。
            byte[] responseBody = method.getResponseBody();

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

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

          POST方法

          根據(jù)RFC2616,對POST的解釋如下:POST方法用來向目的服務(wù)器發(fā)出請求,要求它接受被附在請求后的實(shí)體,并把它當(dāng)作請求隊(duì)列(Request-Line)中請求URI所指定資源的附加新子項(xiàng)。POST被設(shè)計(jì)成用統(tǒng)一的方法實(shí)現(xiàn)下列功能:

          • 對現(xiàn)有資源的注釋(Annotation of existing resources)
          • 向電子公告欄、新聞組,郵件列表或類似討論組發(fā)送消息
          • 提交數(shù)據(jù)塊,如將表單的結(jié)果提交給數(shù)據(jù)處理過程
          • 通過附加操作來擴(kuò)展數(shù)據(jù)庫

          調(diào) 用HttpClient中的PostMethod與GetMethod類似,除了設(shè)置PostMethod的實(shí)例與GetMethod有些不同之外,剩下 的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方,并以登錄清華大學(xué)BBS為例子進(jìn)行說明。

          構(gòu) 造PostMethod之前的步驟都相同,與GetMethod一樣,構(gòu)造PostMethod也需要一個(gè)URI參數(shù),在本例中,登錄的地址是http: //www.newsmth.net/bbslogin2.php。在創(chuàng)建了PostMethod的實(shí)例之后,需要給method實(shí)例填充表單的值,在 BBS的登錄表單中需要有兩個(gè)域,第一個(gè)是用戶名(域名叫id),第二個(gè)是密碼(域名叫passwd)。表單中的域用類NameValuePair來表 示,該類的構(gòu)造函數(shù)第一個(gè)參數(shù)是域名,第二參數(shù)是該域的值;將表單所有的值設(shè)置到PostMethod中用方法setRequestBody。另外由于 BBS登錄成功后會轉(zhuǎn)向另外一個(gè)頁面,但是HttpClient對于要求接受后繼服務(wù)的請求,比如POST和PUT,不支持自動轉(zhuǎn)發(fā),因此需要自己對頁面 轉(zhuǎn)向做處理。具體的頁面轉(zhuǎn)向處理請參見下面的"自動轉(zhuǎn)向"部分。代碼如下:
          String url = "http://www.newsmth.net/bbslogin2.php";
          PostMethod postMethod = new PostMethod(url);
          // 填入各個(gè)表單域的值
          NameValuePair[] data = { new NameValuePair("id", "youUserName"),
          new NameValuePair("passwd", "yourPwd") };
          // 將表單的值放入postMethod中
          postMethod.setRequestBody(data);
          // 執(zhí)行postMethod
          int statusCode = httpClient.executeMethod(postMethod);
          // HttpClient對于要求接受后繼服務(wù)的請求,象POST和PUT等不能自動處理轉(zhuǎn)發(fā)
          // 301或者302
          if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
          statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
          // 從頭中取出轉(zhuǎn)向的地址
          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/,你可以在這里得到關(guān)于HttpClient更加詳細(xì)的信息

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

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(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
          主站蜘蛛池模板: 芮城县| 枝江市| 保康县| 买车| 新宁县| 大安市| 昌吉市| 剑阁县| 浦北县| 革吉县| 和田市| 玉门市| 鸡东县| 金华市| 永丰县| 天台县| 阿拉善盟| 昌都县| 武穴市| 界首市| 乐亭县| 咸阳市| 金乡县| 阿尔山市| 大新县| 洛宁县| 策勒县| 蒙城县| 仪陇县| 台州市| 远安县| 九寨沟县| 麦盖提县| 蒲江县| 浪卡子县| 通渭县| 罗城| 法库县| 海林市| 古交市| 金川县|