apache/commons/httpclient學習筆記

參考資料:
http://www.systinet.com/doc/wasp_uddi/uddi/igpreliminary.html
教程中的一個例程,能夠下載
來源:竹筍炒肉

雖然用telnet這樣的程序均可把頁面取回來,可是在與web服務器的交互中,若是涉及cookie或https或ssl等內容,通常功能相對完備的http客戶端仍是很是必要的。IE或NetScape等瀏覽器確實不錯,但是若是爲實現持續互動而在程序調用瀏覽器,我我的認爲其中的工做量仍是不小的,這還沒考慮版權問題。最好的辦法,就是能有一個開源的包,能實現http客戶端的功能,供咱們開發的程序調用。httpclient就是這麼一個包,我相信可能有比它的實現更好的,但目前我只關注這個。:)
html

下面是nogoop作的功能比較表:
java

Features nogoop Sun JRE < 1.4.2 Sun JRE 1.4.2 Innovation Apache/Jakarta
cookies X X
plug compatible X X X X [partial]
true request output stream X X
true response input stream X X X
connection keep alive X X X X X
connection pool throttling X X
connection/request timeout X X [uns] X X
idle connection timeout X X
pipelining of requests X
alternate DNS resolution (dnsjava) X
SSL X X X X X
basic authentication X X X X X
digest authentication X X X X X
NTLM authentication X [Windows only] X
proxy authentication X X X X X
minimum JRE version 1.2 1 01年4月2日 1.2 1.2
price $499 free free free free
source available X X X
diagnostic tracing X X X
actively supported X X X X
fix turnaround fast slow slow none medium
license purchase Sun JRE Sun JRE LGPL Apache

一、HttpClient的功能



  1. 基於標準,純正java,實現了http1.0和1.1。
  2. 在一個可擴展的OO框架內,實現了HTTP的所有方法(GET, POST, 
    PUT, DELETE, HEAD, OPTIONS, and TRACE)
  3. 支持HTTPS(ssl上的HTTP)的加密操做
  4. 透明地穿過HTTP代理創建鏈接
  5. 經過CONNECT方法,利用經過創建穿過HTTP代理的HTTPS鏈接
  6. 利用本地Java socket,透明地穿過SOCKS(版本5和4)代理創建鏈接
  7. 支持利用Basic、Digest和NTLM加密的認證
  8. 支持用於上傳大文件的Multi-Part表單POST方法
  9. 插件式安全socket實現,易於使用第三方的解決方案
  10. 鏈接管理,支持多線程應用,支持設定單個主機總鏈接和最高鏈接數量,自動檢測和關閉失效鏈接
  11. 直接將請求信息流送到服務器的端口
  12. 直接讀取從服務器的端口送出的應答信息
  13. 支持HTTP/1.0中用KeepAlive和HTTP/1.1中用persistance設置的持久鏈接
  14. 直接訪問由服務器送出的應答代碼和頭部信息
  15. 可設置鏈接超時時間

  16. HttpMethods 實現Command Pattern,以容許並行請求或高效鏈接複用
  17. 遵循the Apache Software License協議,源碼免費可得 

二、預備工做


對jre1.3.*,若是要HttpClient支持https,則須要下載並安裝 jssejce.安裝的步驟以下:
1)下載jsse和jce.
2)檢查CLASSPATH中沒有與jsse和jce相關的jar包
3)將 US_export_policy.jar、local_policy.jar、jsse.jar、jnet.jar、jce1_2_x.jar、sunjce_provider.jar、jcert.jar複製到目錄:
UNIX:$JDK_HOME/jre/lib/ext
Windows:%JDK_HOME%\jre\lib\ext
4)修改下述目錄下的java.security文件。
UNIX:$JDK_HOME/jre/lib/security/
Windows:%JDK_HOME%\jre\lib\security\
5)

#
# List of providers and their preference orders:
#
security.provider.1=sun.security.provider.Sun
security.provider.2=com.sun.rsajca.Provider
改成:
#
# List of providers and their preference orders:
#
security.provider.1=com.sun.crypto.provider.SunJCE
security.provider.2=sun.security.provider.Sun
security.provider.3=com.sun.rsajca.Provider
security.provider.4=com.sun.net.ssl.internal.ssl.Provider

HttpClient還要求安裝commons-logging,下面跟httpclient一塊安裝。

三、取得源碼


cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
password: anoncvs
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/logging
cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout jakarta-commons/httpclient

編譯:
cd jakarta-commons/logging
ant dist
cp dis/*.jar ../httpclient/lib/
cd ../httpclient
ant dist

四、使用HttpClient編程的基本步聚


  1. 建立 HttpClient 的一個實例.
  2. 建立某個方法(DeleteMethod,EntityEnclosingMethod,ExpectContinueMethod,GetMethod,HeadMethod,MultipartPostMethod,OptionsMethod,PostMethod,PutMethod,TraceMethod)的一個實例,通常可用要目標URL爲參數。
  3. 讓 HttpClient 執行這個方法.
  4. 讀取應答信息.
  5. 釋放鏈接.
  6. 處理應答.

在執行方法的過程當中,有兩種異常,一種是HttpRecoverableException,表示偶然性錯誤發生,通常再試可能成功,另外一種是IOException,嚴重錯誤。
這兒有這個教程中的一個例程,能夠 下載



下面學習與http客戶端相關的認證、重定向等內容。

一、認證


HttpClient三種不一樣的認證方案: Basic, Digest and NTLM. 這些方案可用於服務器或代理對客戶端的認證,簡稱服務器認證或代理認證。
1)服務器認證(Server Authentication)
HttpClient處理服務器認證幾乎是透明的,僅須要開發人員提供登陸信息(login credentials)。登陸信息保存在HttpState類的實例中,能夠經過 setCredentials(String realm, Credentials cred)和getCredentials(String realm)來獲取或設置。注意,設定對非特定站點訪問所須要的登陸信息,將realm參數置爲null. HttpClient內建的自動認證,能夠經過HttpMethod類的setDoAuthentication(boolean doAuthentication)方法關閉,並且此次關閉隻影響HttpMethod當前的實例。
搶先認證(Preemptive Authentication)能夠經過下述方法打開.
client.getState().setAuthenticationPreemptive(true);
在這種模式時,HttpClient會主動將basic認證應答信息傳給服務器,即便在某種狀況下服務器可能返回認證失敗的應答,這樣作主要是爲了減小鏈接的創建。爲使每一個新建的 HttpState實例都實行搶先認證,能夠以下設置系統屬性。
setSystemProperty(Authenticator.PREEMPTIVE_PROPERTY, "true");

Httpclient實現的搶先認證遵循rfc2617.
2)代理認證(proxy authentication)
除了登陸信息需單獨存放之外,代理認證與服務器認證幾乎一致。用 setProxyCredentials(String realm, Credentials cred)和 getProxyCredentials(String realm)設、取登陸信息。
3)認證方案(authentication schemes)
Basic
是HTTP中規定最先的也是最兼容(?)的方案,遺憾的是也是最不安全的一個方案,由於它以明碼傳送用戶名和密碼。它要求一個UsernamePasswordCredentials實例,能夠指定服務器端的訪問空間或採用默認的登陸信息。
Digest
是在HTTP1.1中增長的一個方案,雖然不如Basic獲得的軟件支持多,但仍是有普遍的使用。Digest方案比Basic方案安全得多,因它根本就不經過網絡傳送實際的密碼,傳送的是利用這個密碼對從服務器傳來的一個隨機數(nonce)的加密串。它要求一個UsernamePasswordCredentials實例,能夠指定服務器端的訪問空間或採用默認的登陸信息。
NTLM
這是HttpClient支持的最複雜的認證協議。它M$設計的一個私有協議,沒有公開的規範說明。一開始因爲設計的缺陷,NTLM的安全性比Digest差,後來通過一個ServicePack補丁後,安全性則比較Digest高。NTLM須要一個NTCredentials實例. 注意,因爲NTLM不使用訪問空間(realms)的概念,HttpClient利用服務器的域名做訪問空間的名字。還須要注意,提供給NTCredentials的用戶名,不要用域名的前綴 - 如: "adrian" 是正確的,而 "DOMAIN\adrian" 則是錯的.
NTLM認證的工做機制與basic和digest有很大的差異。這些差異通常由HttpClient處理,但理解這些差異有助避免在使用NTLM認證時出現錯誤。
  1. 從HttpClientAPI的角度來看,NTLM與其它認證方式同樣的工做,差異是須要提供'NTCredentials'實例而不是'UsernamePasswordCredentials'(其實,前者只是擴展了後者)
  2. 對NTLM認證,訪問空間是鏈接到的機器的域名,這對多域名主機會有一些麻煩.只有HttpClient鏈接中指定的域名纔是認證用的域名。建議將realm設爲null以使用默認的設置。
  3. NTLM只是認證了一個鏈接而不是一請求,因此每當一個新的鏈接創建就要進行一次認證,且在認證的過程當中保持鏈接是很是重要的。 所以,NTLM不能同時用於代理認證和服務器認證,也不能用於http1.0鏈接或服務器不支持持久鏈接的狀況。

二、重定向


因爲技術限制,以及爲保證2.0發佈版API的穩定,HttpClient還不能自動處重定向,但對重定向到同一主機、同一端口且採用同一協議的狀況HttpClient能夠支持。不能自動的處理的狀況,包括須要人工交互的狀況,或超出httpclient的能力。
當服務器重定向指令指到不一樣的主機時,HttpClient只是簡單地將重定向狀態碼做爲應答狀態。全部的300到399(包含兩端)的返回碼,都表示是重定向應答。常見的有:
  1. 301 永久移動. HttpStatus.SC_MOVED_PERMANENTLY
  2. 302 臨時移動. HttpStatus.SC_MOVED_TEMPORARILY
  3. 303 See Other. HttpStatus.SC_SEE_OTHER
  4. 307 臨時重定向. HttpStatus.SC_TEMPORARY_REDIRECT

當收到簡單的重定向時,程序應從HttpMethod對象中抽取新的URL並將其下載。另外,限制一下重定向次數是個好的主意,這能夠避免遞歸循環。新的URL能夠從頭字段Location中抽取,以下:
String redirectLocation;
Header locationHeader = method.getResponseHeader("location");
if (locationHeader != null) {
redirectLocation = locationHeader.getValue();
} else {
// The response is invalid and did not provide the new location for
// the resource. Report an error or possibly handle the response
// like a 404 Not Found error.
}

特殊重定向:
  1. 300 多重選擇. HttpStatus.SC_MULTIPLE_CHOICES
  2. 304 沒有改動. HttpStatus.SC_NO T_MODIFIED
  3. 305 使用代理. HttpStatus.SC_USE_PROXY
相關文章
相關標籤/搜索