3.2 HttpClient
■ 概況:這個(gè)API擴(kuò)展了java.net包,提供了模擬瀏覽器的功能。
■ 官方資源:主頁,二進(jìn)制,源代碼。
■ 何時(shí)適用:當(dāng)你要構(gòu)造Web瀏覽器的功能;當(dāng)你的應(yīng)用需要一種高效的辦法進(jìn)行HTTP/HTTPS通信時(shí)。
■ 示例應(yīng)用:HttpClientDemo.java。要求CLASSPATH中有commons-httpclient.jar,common-logging.jar。要求使用JDK 1.4或更高版本。
■ 說明:
HttpClient擴(kuò)展和增強(qiáng)了標(biāo)準(zhǔn)java.net包,是一個(gè)內(nèi)容廣泛的代碼庫,功能極其豐富,能夠構(gòu)造出各種使用HTTP協(xié)議的分布式應(yīng)用,或者也可以嵌入到現(xiàn)有應(yīng)用,為應(yīng)用增加訪問HTTP協(xié)議的能力。在Commons穩(wěn)定版中,HttpClient的文檔似乎要比其他包更完善一些,而且還帶有幾個(gè)實(shí)例。下面我們通過一個(gè)簡(jiǎn)單的例子來了解如何提取一個(gè)Web頁面,HttpClient文檔中也有一個(gè)類似的例子,我們將擴(kuò)充那個(gè)例子使其支持SSL。注意本例需要JDK 1.4支持,因?yàn)樗玫絁ava Secure Socket Connection庫,而這個(gè)庫只有JDK 1.4及更高的版本才提供。
① 首先確定一個(gè)可以通過HTTPS下載的頁面,本例使用的是https://www.paypal.com/。同時(shí)確保%JAVA_HOME%/jre/lib/security/java.security文件包含了下面這行代碼:security.provider.2=com.sun.net.ssl.internal.ssl.Provider。
除了這些設(shè)置之外,HTTPS連接的處理方式?jīng)]有其他特別的地方--至少對(duì)于本例來說如此。不過,如果遠(yuǎn)程網(wǎng)站使用的根證書不被你使用的Java認(rèn)可,則首先必須導(dǎo)入它的證書。
② 創(chuàng)建一個(gè)HttpClient的實(shí)例。HttpClient類可以看成是應(yīng)用的主驅(qū)動(dòng)程序,所有針對(duì)網(wǎng)絡(luò)的功能都依賴于它。HttpClient類需要一個(gè)Connection Manager來管理連接。HttpConnectionManager允許我們創(chuàng)建自己的連接管理器,或者,我們也可以直接使用內(nèi)建的SimpleHttpConnectionManager或MultiThreadedHttpConnectionManager類。如果在創(chuàng)建HttpClient時(shí)沒有指定連接管理器,HttpClient默認(rèn)使用SimpleHttpConnectionManager。
//
?創(chuàng)建一個(gè)HttpClient的實(shí)例
HttpClient?client?
=
?
new
?HttpClient();
③ 創(chuàng)建一個(gè)HttpMethod的實(shí)例,即確定與遠(yuǎn)程服務(wù)器的通信要采用哪種傳輸方式,HTTP允許采用的傳輸方式包括:GET,POST,PUT,DELETE,HEAD,OPTIONS,以及TRACE。這些傳輸方式分別作為一個(gè)獨(dú)立的類實(shí)現(xiàn),但所有這些類都實(shí)現(xiàn)HttpMethod接口。在本例中,我們使用的是GetMethod,創(chuàng)建GetMethod實(shí)例時(shí)在參數(shù)中指定我們想要GET的URL。
//?創(chuàng)建一個(gè)HttpMethod的實(shí)例
HttpMethod?method?=?new?GetMethod(url);
?

④ 執(zhí)行HttpMethod定義的提取操作。執(zhí)行完畢后,executeMethod方法將返回遠(yuǎn)程服務(wù)器報(bào)告的狀態(tài)代碼。注意executeMethod屬于HttpClient,而不是HttpMethod。
//?執(zhí)行HttpMethod定義的提取操作
statusCode?=?client.executeMethod(method);⑤ 讀取服務(wù)器返回的應(yīng)答。如果前面的連接操作失敗,程序?qū)⒂龅紿ttpException或IOException,其中IOException一般意味著網(wǎng)絡(luò)出錯(cuò),繼續(xù)嘗試也不太可能獲得成功。服務(wù)器返回的應(yīng)答可以按照多種方式讀取,例如作為一個(gè)字節(jié)數(shù)組,作為一個(gè)輸入流,或者作為一個(gè)String。獲得服務(wù)器返回的應(yīng)答后,我們就可以按照自己的需要任意處置它了。
byte[]?responseBody?=?method.getResponseBody();

⑥ 最后要做的就是釋放連接。
method.releaseConnection(); 以上只是非常簡(jiǎn)單地介紹了一下HttpClient庫,HttpClient實(shí)際的功能要比本文介紹的豐富得多,不僅健壯而且高效,請(qǐng)參閱API文檔了解詳情。
3.3 Net
■ 概況:一個(gè)用于操作Internet基礎(chǔ)協(xié)議的底層API。
■ 官方資源:主頁,二進(jìn)制,源代碼。
■ 何時(shí)適用:當(dāng)你想要訪問各種Internet底層協(xié)議之時(shí)(Finger,Whois,TFTP,Telnet,POP3,F(xiàn)TP,NNTP,以及SMTP)。
■ 示例應(yīng)用:NetDemo.java。要求CLASSPATH中包含commons-net-1.0.0.jar。
■ 說明:
Net包是一個(gè)強(qiáng)大、專業(yè)的類庫,類庫里的類最初屬于一個(gè)叫做NetComponents的商業(yè)產(chǎn)品。
Net包不僅支持對(duì)各種低層次協(xié)議的訪問,而且還提供了一個(gè)高層的抽象。大多數(shù)情況下,Net包提供的抽象已能滿足一般需要,它使得開發(fā)者不再需要直接面對(duì)各種協(xié)議的Socket級(jí)的低層命令。使用高層抽象并不減少任何功能,Net API在這方面做得很出色,既提供了足夠的功能,又不至于在特色方面作過多的妥協(xié)。
SocketClient是支持所有協(xié)議的基礎(chǔ)類,它是一個(gè)抽象類,聚合了各種協(xié)議都需要的公用功能。各種不同協(xié)議的使用過程其實(shí)很相似,首先利用connect方法建立一個(gè)指向遠(yuǎn)程服務(wù)器的連接,執(zhí)行必要的操作,最后終止與服務(wù)器的連接。下面通過實(shí)例介紹具體的使用步驟。
//?…
//?①?創(chuàng)建一個(gè)客戶端。我們將用NNTPClient
// 從新聞服務(wù)器下載新聞組清單。
client?=?new?NNTPClient();
//?…
//?②?利用前面創(chuàng)建的客戶端連接到新聞服務(wù)器。
// 這里選用的是一個(gè)新聞組較少的服務(wù)器。
client.connect("aurelia.deine.net");
//?…
//?③?提取新聞組清單。下面的命令將返回一個(gè)
// NewsGroupInfo對(duì)象的數(shù)組。如果指定的服
// 務(wù)器上不包含新聞組,返回的數(shù)組將是空的,
// 如果遇到了錯(cuò)誤,則返回值是null。
list?=?client.listNewsgroups();
//
//?④?最后終止與服務(wù)器的連接。
?if?(client.isConnected())
???client.disconnect();必須說明的是,listNewsgroups命令可能需要較長的時(shí)間才能返回,一方面是因?yàn)榫W(wǎng)絡(luò)速度的影響,另外也可能是由于新聞組清單往往是很龐大的。NewsGroupInfo對(duì)象包含有關(guān)新聞組的詳細(xì)信息,并提供了一些操作新聞組的命令,比如提取文章總數(shù)、最后發(fā)布的文章、發(fā)布文章的權(quán)限,等等。
其他客戶端,例如FingerClient、POP3Client、TelnetClient等,用法也差不多。
結(jié)束語:有關(guān)Web相關(guān)類和其他類的介紹就到此結(jié)束。在下一篇文章中,我們將探討XML類和包裝類,最后一篇文章則介紹工具類。
希望讀者有興趣試試本文提供的程序?qū)嵗:芏鄷r(shí)候Jakarta Commons給人以混亂的感覺,希望本文使你加深了對(duì)Jakarta Commons了解,或者至少引起了你對(duì)Commons子項(xiàng)目以及它提供的各種實(shí)用API和庫的興趣。
請(qǐng)從這里下載本文代碼:JakartaCommons1_code.zip