HTTP 協(xié)議可能是現(xiàn)在 Internet 上使用得最多、最重要的協(xié)議了,越來(lái)越多的 Java 應(yīng)用程序需要直接通過(guò) HTTP 協(xié)議來(lái)訪問(wèn)網(wǎng)絡(luò)資源。雖然在 JDK 的 java.net 包中已經(jīng)提供了訪問(wèn) HTTP 協(xié)議的基本功能,但是對(duì)于大部分應(yīng)用程序來(lái)說(shuō),JDK 庫(kù)本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項(xiàng)目,用來(lái)提供高效的、最新的、功能豐富的支持 HTTP 協(xié)議的客戶(hù)端編程工具包,并且它支持 HTTP 協(xié)議最新的版本和建議。HttpClient 已經(jīng)應(yīng)用在很多的項(xiàng)目中,比如 Apache Jakarta 上很著名的另外兩個(gè)開(kāi)源項(xiàng)目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應(yīng)用可以參見(jiàn)http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項(xiàng)目非常活躍,使用的人還是非常多的。目前 HttpClient 版本是在 2005.10.11 發(fā)布的 3.0 RC4 。
![]() ![]() |
![]()
|
以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細(xì)的功能可以參見(jiàn) HttpClient 的主頁(yè)。
下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。
![]() ![]() |
![]()
|
使用 HttpClient 需要以下 6 個(gè)步驟:
1. 創(chuàng)建 HttpClient 的實(shí)例
2. 創(chuàng)建某種連接方法的實(shí)例,在這里是 GetMethod。在 GetMethod 的構(gòu)造函數(shù)中傳入待連接的地址
3. 調(diào)用第一步中創(chuàng)建好的實(shí)例的 execute 方法來(lái)執(zhí)行第二步中創(chuàng)建好的 method 實(shí)例
4. 讀 response
5. 釋放連接。無(wú)論執(zhí)行方法是否成功,都必須釋放連接
6. 對(duì)得到后的內(nèi)容進(jìn)行處理
根據(jù)以上步驟,我們來(lái)編寫(xiě)用GET方法來(lái)取得某網(wǎng)頁(yè)內(nèi)容的代碼。
HttpClient httpClient = new HttpClient(); |
GetMethod getMethod = new GetMethod("http://www.ibm.com/"); |
//設(shè)置成了默認(rèn)的恢復(fù)策略,在發(fā)生異常時(shí)候?qū)⒆詣?dòng)重試3次,在這里你也可以設(shè)置成自定義的恢復(fù)策略 |
byte[] responseBody = method.getResponseBody(); |
method.releaseConnection(); |
System.out.println(new String(responseBody)); |
下面是程序的完整代碼,這些代碼也可在附件中的test.GetSample中找到。
package test; |
根據(jù)RFC2616,對(duì)POST的解釋如下:POST方法用來(lái)向目的服務(wù)器發(fā)出請(qǐng)求,要求它接受被附在請(qǐng)求后的實(shí)體,并把它當(dāng)作請(qǐng)求隊(duì)列 (Request-Line)中請(qǐng)求URI所指定資源的附加新子項(xiàng)。POST被設(shè)計(jì)成用統(tǒng)一的方法實(shí)現(xiàn)下列功能:
調(diào)用HttpClient中的PostMethod與GetMethod類(lèi)似,除了設(shè)置PostMethod的實(shí)例與GetMethod有些 不同之外,剩下的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說(shuō)明與上面不同的地方,并以登錄清華大學(xué)BBS為例子進(jìn)行說(shuō) 明。
String url = "http://www.newsmth.net/bbslogin2.php"; |
完整的程序代碼請(qǐng)參見(jiàn)附件中的test.PostSample
![]() ![]() |
![]()
|
使用HttpClient過(guò)程中常見(jiàn)的一些問(wèn)題
下面介紹在使用HttpClient過(guò)程中常見(jiàn)的一些問(wèn)題。
某目標(biāo)頁(yè)的編碼可能出現(xiàn)在兩個(gè)地方,第一個(gè)地方是服務(wù)器返回的http頭中,另外一個(gè)地方是得到的html/xml頁(yè)面中。
根據(jù)RFC2616中對(duì)自動(dòng)轉(zhuǎn)向的定義,主要有兩種:301和302。301表示永久的移走(Moved Permanently),當(dāng)返回的是301,則表示請(qǐng)求的資源已經(jīng)被移到一個(gè)固定的新地方,任何向該地址發(fā)起請(qǐng)求都會(huì)被轉(zhuǎn)到新的地址上。302表示暫時(shí) 的轉(zhuǎn)向,比如在服務(wù)器端的servlet程序調(diào)用了sendRedirect方法,則在客戶(hù)端就會(huì)得到一個(gè)302的代碼,這時(shí)服務(wù)器返回的頭信息中 location的值就是sendRedirect轉(zhuǎn)向的目標(biāo)地址。
HttpClient支持自動(dòng)轉(zhuǎn)向處理,但是象POST和PUT方式這種要求接受后繼服務(wù)的請(qǐng)求方式,暫時(shí)不支持自動(dòng)轉(zhuǎn)向,因此如果碰到 POST方式提交后返回的是301或者302的話(huà)需要自己處理。就像剛才在POSTMethod中舉的例子:如果想進(jìn)入登錄BBS后的頁(yè)面,必須重新發(fā)起 登錄的請(qǐng)求,請(qǐng)求的地址可以在頭字段location中得到。不過(guò)需要注意的是,有時(shí)候location返回的可能是相對(duì)路徑,因此需要對(duì) location返回的值做一些處理才可以發(fā)起向新地址的請(qǐng)求。
另外除了在頭中包含的信息可能使頁(yè)面發(fā)生重定向外,在頁(yè)面中也有可能會(huì)發(fā)生頁(yè)面的重定向。引起頁(yè)面自動(dòng)轉(zhuǎn)發(fā)的標(biāo)簽是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也處理這種情況的話(huà)得自己分析頁(yè)面來(lái)實(shí)現(xiàn)轉(zhuǎn)向。需要注意的是,在上面那 個(gè)標(biāo)簽中url的值也可以是一個(gè)相對(duì)地址,如果是這樣的話(huà),需要對(duì)它做一些處理后才可以轉(zhuǎn)發(fā)。
HttpClient提供了對(duì)SSL的支持,在使用SSL之前必須安裝JSSE。在Sun提供的1.4以后的版本中,JSSE已經(jīng)集成到 JDK中,如果你使用的是JDK1.4以前的版本則必須安裝JSSE。JSSE不同的廠家有不同的實(shí)現(xiàn)。下面介紹怎么使用HttpClient來(lái)打開(kāi) Https連接。這里有兩種方法可以打開(kāi)https連接,第一種就是得到服務(wù)器頒發(fā)的證書(shū),然后導(dǎo)入到本地的keystore中;另外一種辦法就是通過(guò)擴(kuò) 展HttpClient的類(lèi)來(lái)實(shí)現(xiàn)自動(dòng)接受證書(shū)。
方法1,取得證書(shū),并導(dǎo)入本地的keystore:
1. 用IE打開(kāi)需要連接的https網(wǎng)址,會(huì)彈出如下對(duì)話(huà)框:
2. 單擊"View Certificate",在彈出的對(duì)話(huà)框中選擇"Details",然后再單擊"Copy to File",根據(jù)提供的向?qū)纱L問(wèn)網(wǎng)頁(yè)的證書(shū)文件
3. 向?qū)У谝徊剑瑲g迎界面,直接單擊"Next",
4. 向?qū)У诙剑x擇導(dǎo)出的文件格式,默認(rèn),單擊"Next",
5. 向?qū)У谌剑斎雽?dǎo)出的文件名,輸入后,單擊"Next",
6. 向?qū)У谒牟剑瑔螕?Finish",完成向?qū)?/p>
7. 最后彈出一個(gè)對(duì)話(huà)框,顯示導(dǎo)出成功
用keytool工具把剛才導(dǎo)出的證書(shū)倒入本地keystore。Keytool命令在<java-home>"bin "下,打開(kāi)命令行窗口,并到<java-home>"lib"security"目錄下,運(yùn)行下面的命令:
keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer |
其中參數(shù)alias后跟的值是當(dāng)前證書(shū)在keystore中的唯一標(biāo)識(shí)符,但是大小寫(xiě)不區(qū)分;參數(shù)file后跟的是剛才通過(guò)IE導(dǎo)出的證 書(shū)所在的路徑和文件名;如果你想刪除剛才導(dǎo)入到keystore的證書(shū),可以用命令:
keytool -delete -keystore cacerts -storepass changeit -alias yourEntry1 |
GetMethod getMethod = new GetMethod("https://www.yourdomain.com"); |
運(yùn)行該程序可能出現(xiàn)的問(wèn)題:
1. 拋出異常java.net.SocketException: Algorithm SSL not available。出現(xiàn)這個(gè)異常可能是因?yàn)闆](méi)有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入這樣的一行:
if(Security.getProvider("com.ibm.jsse.IBMJSSEProvider") == null) |
或者也可以打開(kāi)<java-home>"lib"security"java.security,在行
security.provider.1=sun.security.provider.Sun |
后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider
2. 拋出異常java.net.SocketException: SSL implementation not available。出現(xiàn)這個(gè)異常可能是你沒(méi)有把ibmjsse.jar拷貝到<java-home>"lib"ext"目錄下。
3. 拋出異常javax.net.ssl.SSLHandshakeException: unknown certificate。出現(xiàn)這個(gè)異常表明你的JSSE應(yīng)該已經(jīng)安裝正確,但是可能因?yàn)槟銢](méi)有把證書(shū)導(dǎo)入到當(dāng)前運(yùn)行JRE的keystore中,請(qǐng)按照前 面介紹的步驟來(lái)導(dǎo)入你的證書(shū)。
方法2,擴(kuò)展HttpClient類(lèi)實(shí)現(xiàn)自動(dòng)接受證書(shū)
因?yàn)檫@種方法自動(dòng)接收所有證書(shū),因此存在一定的安全問(wèn)題,所以在使用這種方法前請(qǐng)仔細(xì)考慮您的系統(tǒng)的安全需求。具體的步驟如下:
Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443); |
Protocol.registerProtocol("https ", myhttps); |
HttpClient中使用代理服務(wù)器非常簡(jiǎn)單,調(diào)用HttpClient中setProxy方法就可以,方法的第一個(gè)參數(shù)是代理服務(wù)器地 址,第二個(gè)參數(shù)是端口號(hào)。另外HttpClient也支持SOCKS代理。
httpClient.getHostConfiguration().setProxy(hostName,port); |
![]() ![]() |
![]()
|
從上面的介紹中,可以知道HttpClient對(duì)http協(xié)議支持非常好,使用起來(lái)很簡(jiǎn)單,版本更新快,功能也很強(qiáng)大,具有足夠的靈活性和擴(kuò) 展性。對(duì)于想在Java應(yīng)用中直接訪問(wèn)http資源的編程人員來(lái)說(shuō),HttpClient是一個(gè)不可多得的好工具。
一、下載:
http://jadclipse.sourceforge.net/wiki/index.php/Main_Page#Download(jdaclipse插件主頁(yè))
下載插件:
This release stream is appropriate for Eclipse 3.3.
Filename | Size | Description |
---|---|---|
net.sf.jadclipse_3.3.0.jar | 45 KB | JadClipse for Eclipse >= 3.3M6 |
This release stream is appropriate for Eclipse 3.2.
Filename | Size | Description |
---|---|---|
net.sf.jadclipse_3.2.4.jar | 45 KB | JadClipse for Eclipse >= 3.2M5 |
jadclipse_3.2.0.jar | 54 KB | JadClipse for Eclipse 3.2M3 and M4 |
This release stream is appropriate for Eclipse 3.1.
Filename | Size | Description |
---|---|---|
jadclipse_3.1.0.jar | 54 KB | JadClipse for Eclipse 3.1 (including milestone builds starting from 3.1M6 up to 3.2M2) |
myeclipse6.0 就下載JadClipse 3.3
下載Jad反編譯工具:
http://www.varaneckas.com/jad,在該頁(yè)中找到適合自己操作系統(tǒng)平臺(tái)的jad下載。下載后解壓,然后將解壓后的jad.exe文件復(fù)制到%JAVA_HOME%"bin目錄下面(可以將jad.exe放到任意位置,只要記住其存放路徑就好,下面要用到)。
二、安裝:
Eclipse中的插件安裝可以參考:
方法1、直接將x.x.x.jar(x.x.x.代表版本號(hào))復(fù)制到%ECLIPSE_HOME%"plugins目錄下。
方法2、使用link方式安裝,建立D:"Myplugins"jadclipse3.2.4"eclipse"plugins的目錄結(jié)構(gòu),將jadclipse_3.2.4.jar放到plugins目錄下面(注:其中D:"Myplugins為你自己定義的一個(gè)專(zhuān)門(mén)放置插件的目錄)。再在%ECLIPSE_HOME%"links目錄下面建立一個(gè)jadclipse3.2.4.link文件(該文件名隨便取)。文件里面內(nèi)容為:path=D:/Myplugins/jadclipse3.2.4.
三、
使用:
啟動(dòng)eclipse,點(diǎn)擊反編譯的類(lèi)文件,此時(shí)會(huì)激活jadclipse插件,在eclipse菜單中會(huì)多出一個(gè)jadclipse菜單,
如下圖所示:
一般地它會(huì)自動(dòng)
反編譯相應(yīng)的class文件,如果沒(méi)有自動(dòng)反編譯,請(qǐng)點(diǎn)擊
jadclipse->Decompile
如下圖所示:
常見(jiàn)問(wèn)題及解決:
(一)啟動(dòng)eclipse,打開(kāi)Window->Preferences->Java->JadClipse,如果沒(méi)有找到JadClipse,即JadClipse插件沒(méi)有激活。
(1)檢查插件安裝的版 本是否與你安裝的eclipse版本對(duì)應(yīng)
(2)使用 –clean參數(shù)來(lái)啟動(dòng)eclipse
(二)在使用JadClipse插件反編譯class文件時(shí)出現(xiàn)如下類(lèi)似錯(cuò)誤:
/*jadclipse*/
/*
DECOMPILATION REPORT
Decompiled from: D:"Program Files"Java"jdk1.5.0_12"jre"lib"rt.jar
Total time: 16 ms
Jad reported messages/errors:
Exit status: 0
Caught exceptions:
java.io.IOException: CreateProcess: (...)
請(qǐng)確保你的Jad路徑在eclipse中正確制定。
啟動(dòng)eclipse,打開(kāi):Window->Preferences->Java->JadClipse.
1、Path to decompiler,這里設(shè)置反編譯工具jad的全路徑名,比如:%JAVA_HOME%"bin"jad.exe.
2、Directory for temporary files,這里設(shè)置臨時(shí)
文件路徑。
至于Window->Preferences->Java->JadClipse目錄下的Debug,Directives,Formatting,Misc目錄中的參數(shù) 設(shè)置,就不再羅嗦了。
(三)安裝完成后,eclipse沒(méi)有自動(dòng)將JadClipse Class File Viewer設(shè)置成class文件的缺省打開(kāi)方式。
如果沒(méi)有默認(rèn),可以在Eclipse的Windows—> Perference—>General->Editors->File Associations中修改“*.class”默認(rèn)關(guān)聯(lián)的編輯器為“JadClipse Class File Viewer”。設(shè)置完成后,雙擊*.class文件,eclipse將自動(dòng)反編譯。