Jakarta Commons HttpClient 學(xué)習(xí)筆記(轉(zhuǎn))

          1、HttpClient的功能



          1. 基于標準,純正java,實現(xiàn)了http1.0和1.1。
          2. 在一個可擴展的OO框架內(nèi),實現(xiàn)了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實現(xiàn),易于使用第三方的解決方案
          10. 連接管理,支持多線程應(yīng)用,支持設(shè)定單個主機總連接和最高連接數(shù)量,自動檢測和關(guān)閉失效連接
          11. 直接將請求信息流送到服務(wù)器的端口
          12. 直接讀取從服務(wù)器的端口送出的應(yīng)答信息
          13. 支持HTTP/1.0中用KeepAlive和HTTP/1.1中用persistance設(shè)置的持久連接
          14. 直接訪問由服務(wù)器送出的應(yīng)答代碼和頭部信息
          15. 可設(shè)置連接超時時間

          16. HttpMethods 實現(xiàn)Command Pattern,以允許并行請求或高效連接復(fù)用
          17. 遵循the Apache Software License協(xié)議,源碼免費可得

          2、預(yù)備工作


            對jre1.3.*,如果要HttpClient支持https,則需要下載并安裝java.sun.com/products/jsse/">jsse和java.sun.com/products/jce/">jce.安裝的步驟如下:
          1)下載jsse和jce.
          2)檢查CLASSPATH中沒有與jsse和jce相關(guān)的jar包
          3)將 US_export_policy.jar、local_policy.jar、jsse.jar、jnet.jar、jce1_2_x.jar、sunjce_provider.jar、jcert.jar復(fù)制到目錄:
          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一塊安裝。

          3、取得源碼


          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

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


          1. 創(chuàng)建 HttpClient 的一個實例.
          2. 創(chuàng)建某個方法(DeleteMethod,EntityEnclosingMethod,ExpectContinueMethod,GetMethod,HeadMethod,MultipartPostMethod,OptionsMethod,PostMethod,PutMethod,TraceMethod)的一個實例,一般可用要目標URL為參數(shù)。
          3. 讓 HttpClient 執(zhí)行這個方法.
          4. 讀取應(yīng)答信息.
          5. 釋放連接.
          6. 處理應(yīng)答.

            在執(zhí)行方法的過程中,有兩種異常,一種是HttpRecoverableException,表示偶然性錯誤發(fā)生,一般再試可能成功,另一種是IOException,嚴重錯誤。
            這兒有這個教程中的一個例程,可以java">下載。

          5、認證


            HttpClient三種不同的認證方案: Basic, Digest and NTLM. 這些方案可用于服務(wù)器或代理對客戶端的認證,簡稱服務(wù)器認證或代理認證
          1)服務(wù)器認證(Server Authentication)
            HttpClient處理服務(wù)器認證幾乎是透明的,僅需要開發(fā)人員提供登錄信息(login credentials)。登錄信息保存在HttpState類的實例中,可以通過 setCredentials(String realm, Credentials cred)和getCredentials(String realm)來獲取或設(shè)置。注意,設(shè)定對非特定站點訪問所需要的登錄信息,將realm參數(shù)置為null. HttpClient內(nèi)建的自動認證,可以通過HttpMethod類的setDoAuthentication(boolean doAuthentication)方法關(guān)閉,而且這次關(guān)閉只影響HttpMethod當前的實例。
            搶先認證(Preemptive Authentication)可以通過下述方法打開.
          client.getState().setAuthenticationPreemptive(true);
            在這種模式時,HttpClient會主動將basic認證應(yīng)答信息傳給服務(wù)器,即使在某種情況下服務(wù)器可能返回認證失敗的應(yīng)答,這樣做主要是為了減少連接的建立。為使每個新建的 HttpState實例都實行搶先認證,可以如下設(shè)置系統(tǒng)屬性。
          setSystemProperty(Authenticator.PREEMPTIVE_PROPERTY, "true");

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

          6、重定向


            由于技術(shù)限制,以及為保證2.0發(fā)布版API的穩(wěn)定,HttpClient還不能自動處重定向,但對重定向到同一主機、同一端口且采用同一協(xié)議的情況HttpClient可以支持。不能自動的處理的情況,包括需要人工交互的情況,或超出httpclient的能力。
            當服務(wù)器重定向指令指到不同的主機時,HttpClient只是簡單地將重定向狀態(tài)碼作為應(yīng)答狀態(tài)。所有的300到399(包含兩端)的返回碼,都表示是重定向應(yīng)答。常見的有:
          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

            當收到簡單的重定向時,程序應(yīng)從HttpMethod對象中抽取新的URL并將其下載。另外,限制一下重定向次數(shù)是個好的主意,這可以避免遞歸循環(huán)。新的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
            

          7、字符編碼(character encoding)


            一個HTTP協(xié)議的請求或應(yīng)答的頭部(在http協(xié)議中,數(shù)據(jù)包分為兩部分,一部分是頭部,由一些名值對構(gòu)成,一部分是主體(body),是真正傳辦理的數(shù)據(jù)(如HTML頁面等)),必須以US-ASCII編碼,這是因為頭部不傳數(shù)據(jù)而只描述被要傳輸?shù)臄?shù)據(jù)的一些信息,一個例外是cookie,它是數(shù)據(jù)但是通過頭部進行傳輸?shù)模运惨肬S-ASCII編碼。
            HTTP數(shù)據(jù)包的主體部分,可以用任何一種方式進行編碼,默認是ISO-8859-1,具體可以用頭部字段Content-Type指定。可以利用 addRequestHeader方法,設(shè)定編碼方式;用 getResponseCharSet取得編碼方式。對HTML或XML等類型的文檔,它們的本身的Content-Type也可以指定編碼方式,主要區(qū)分兩者的作用范圍以得到正確實的解碼。
            URL的編碼標準,由RFC1738指定為,只能是由可打印8位/字節(jié)的us-ascii字符組成,80-ff不是us-ascii字符,而00-1F是控制字符,這兩個區(qū)域中用的字符都須加以編碼(encoded)。
            

          8、Cookies


             HttpClient能自動管理cookie,包括允許服務(wù)器設(shè)置cookie并在需要的時候自動將cookie返回服務(wù)器,它也支持手工設(shè)置cookie后發(fā)送到服務(wù)器端。不幸的是,對如何處理cookie,有幾個規(guī)范互相沖突:Netscape Cookie 草案, RFC2109, RFC2965,而且還有很大數(shù)量的軟件商的cookie實現(xiàn)不遵循任何規(guī)范. 為了處理這種狀況,HttpClient提供了策略驅(qū)動的cookie管理方式。HttpClient支持的cookie規(guī)范有:
          1. Netscape cookie草案,是最早的cookie規(guī)范,基于rfc2109。盡管這個規(guī)范與rc2109有較大的差別,這樣做可以與一些服務(wù)器兼容。
          2. rfc2109,是w3c發(fā)布的第一個官方cookie規(guī)范。理論上講,所有的服務(wù)器在處理cookie(版本1)時,都要遵循此規(guī)范,正因如此,HttpClient將其設(shè)為默認的規(guī)范。遺憾的是,這個規(guī)范太嚴格了,以致很多服務(wù)器不正確的實施了該規(guī)范或仍在作用Netscape規(guī)范。在這種情況下,應(yīng)使用兼容規(guī)范。
          3. 兼容性規(guī)范,設(shè)計用來兼容盡可能多的服務(wù)器,即使它們并沒有遵循標準規(guī)范。當解析cookie出現(xiàn)問題時,應(yīng)考慮采用兼容性規(guī)范。

             RFC2965規(guī)范暫時沒有被HttpClient支持(在以后的版本為會加上),它定義了cookie版本2,并說明了版本1cookie的不足,RFC2965有意有久取代rfc2109.
            在HttpClient中,有兩種方法來指定cookie規(guī)范的使用,
          1. HttpClient client = new HttpClient();
            client.getState().setCookiePolicy(CookiePolicy.COMPATIBILITY);
            這種方法設(shè)置的規(guī)范只對當前的HttpState有效,參數(shù)可取值CookiePolicy.COMPATIBILITY,CookiePolicy.NETSCAPE_DRAFT或CookiePolicy.RFC2109。
          2. System.setProperty("apache.commons.httpclient.cookiespec", "COMPATIBILITY");
            此法指的規(guī)范,對以后每個新建立的HttpState對象都有效,參數(shù)可取值"COMPATIBILITY","NETSCAPE_DRAFT"或"RFC2109"。
              常有不能解析cookie的問題,但更換到兼容規(guī)范大都能解決。
            

          9、使用HttpClient遇到問題怎么辦?


          1. 用一個瀏覽器訪問服務(wù)器,以確認服務(wù)器應(yīng)答正常
          2. 如果在使代理,關(guān)掉代理試試
          3. 另找一個服務(wù)器來試試(如果運行著不同的服務(wù)器軟件更好)
          4. 檢查代碼是否按教程中講的思路編寫
          5. 設(shè)置log級別為debug,找出問題出現(xiàn)的原因
          6. 打開wiretrace,來追蹤客戶端與服務(wù)器的通信,以確實問題出現(xiàn)在什么地方
          7. 用telnet或netcat手工將信息發(fā)送到服務(wù)器,適合于猜測已經(jīng)找到了原因而進行試驗時
          8. 將netcat以監(jiān)聽方式運行,用作服務(wù)器以檢查httpclient如何處理應(yīng)答的。
          9. 利用最新的httpclient試試,bug可能在最新的版本中修復(fù)了
          10. 向郵件列表求幫助
          11. 向bugzilla報告bug.
            

          10、SSL


            借助Java Secure Socket Extension (JSSE),HttpClient全面支持Secure Sockets Layer (SSL)或IETF Transport Layer Security (TLS)協(xié)議上的HTTP。JSSE已經(jīng)jre1.4及以后的版本中,以前的版本則需要手工安裝設(shè)置,具體過程參見java.sun.com/products/jsse/doc/guide/API_users_guide.html#Installation">Sun網(wǎng)站或本學(xué)習(xí)筆記。
            HttpClient中使用SSL非常簡單,參考下面兩個例子:
          HttpClient httpclient = new HttpClient();
          GetMethod httpget = new GetMethod("https://www.verisign.com/");
          httpclient.executeMethod(httpget);
          System.out.println(httpget.getStatusLine().toString());
          ,如果通過需要授權(quán)的代理,則如下:
          HttpClient httpclient = new HttpClient();
          httpclient.getHostConfiguration().setProxy("myproxyhost", 8080);
          httpclient.getState().setProxyCredentials("my-proxy-realm", " myproxyhost",
          new UsernamePasswordCredentials("my-proxy-username", "my-proxy-password"));
          GetMethod httpget = new GetMethod("https://www.verisign.com/");
          httpclient.executeMethod(httpget);
          System.out.println(httpget.getStatusLine().toString());

            在HttpClient中定制SSL的步驟如下:
          1. 提供了一個實現(xiàn)了org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory接口的socket factory。這個 socket factory負責打一個到服務(wù)器的端口,使用標準的或第三方的SSL函數(shù)庫,并進行象連接握手等初始化操作。通常情況下,這個初始化操作在端口被創(chuàng)建時自動進行的。
          2. 實例化一個org.apache.commons.httpclient.protocol.Protocol對象。創(chuàng)建這個實例時,需要一個合法的協(xié)議類型(如https),一個定制的socket factory,和一個默認的端中號(如https的443端口).
            Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
            然后,這個實例可被設(shè)置為協(xié)議的處理器。
            HttpClient httpclient = new HttpClient();
            httpclient.getHostConfiguration().setHost("www.whatever.com", 443, myhttps);
            GetMethod httpget = new GetMethod("/");
            httpclient.executeMethod(httpget);

          3. 通過調(diào)用Protocol.registerProtocol方法,將此定制的實例,注冊為某一特定協(xié)議的默認的處理器。由此,可以很方便地定制自己的協(xié)議類型(如myhttps)。
            Protocol.registerProtocol("myhttps",
            new Protocol("https", new MySSLSocketFactory(), 9443));
            ...
            HttpClient httpclient = new HttpClient();
            GetMethod httpget = new GetMethod("myhttps://www.whatever.com/");
            httpclient.executeMethod(httpget);
            如果想用自己定制的處理器取代https默認的處理器,只需要將其注冊為"https"即可。
            Protocol.registerProtocol("https",
            new Protocol("https", new MySSLSocketFactory(), 443));
            HttpClient httpclient = new HttpClient();
            GetMethod httpget = new GetMethod("https://www.whatever.com/");
            httpclient.executeMethod(httpget);

            已知的限制和問題
          1. 持續(xù)的SSL連接在Sun的低于1.4JVM上不能工作,這是由于JVM的bug造成。
          2. 通過代理訪問服務(wù)器時,非搶先認證( Non-preemptive authentication)會失敗,這是由于HttpClient的設(shè)計缺陷造成的,以后的版本中會修改。

            遇到問題的處理
            很多問題,特別是在jvm低于1.4時,是由jsse的安裝造成的。
            下面的代碼,可作為最終的檢測手段。
          import java.io.BufferedReader;
          import java.io.InputStreamReader;
          import java.io.OutputStreamWriter;
          import java.io.Writer;
          import java.net.Socket; import javax.net.ssl.SSLSocketFactory; public class Test {

          public static final String TARGET_HTTPS_SERVER = "www.verisign.com";
          public static final int TARGET_HTTPS_PORT = 443;

          public static void main(String[] args) throws Exception {

          Socket socket = SSLSocketFactory.getDefault().
          createSocket(TARGET_HTTPS_SERVER, TARGET_HTTPS_PORT);
          try {
          Writer out = new OutputStreamWriter(
          socket.getOutputStream(), "ISO-8859-1");
          out.write("GET / HTTP/1.1\r\n");
          out.write("Host: " + TARGET_HTTPS_SERVER + ":" +
          TARGET_HTTPS_PORT + "\r\n");
          out.write("Agent: SSL-TEST\r\n");
          out.write("\r\n");
          out.flush();
          BufferedReader in = new BufferedReader(
          new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
          String line = null;
          while ((line = in.readLine()) != null) {
          System.out.println(line);
          }
          } finally {
          socket.close();
          }
          }
          }

            

          11、httpclient的多線程處理


            使用多線程的主要目的,是為了實現(xiàn)并行的下載。在httpclient運行的過程中,每個http協(xié)議的方法,使用一個HttpConnection實例。由于連接是一種有限的資源,每個連接在某一時刻只能供一個線程和方法使用,所以需要確保在需要時正確地分配連接。HttpClient采用了一種類似jdbc連接池的方法來管理連接,這個管理工作由 MultiThreadedHttpConnectionManager完成。
          MultiThreadedHttpConnectionManager connectionManager =
          new MultiThreadedHttpConnectionManager();
          HttpClient client = new HttpClient(connectionManager);
          此是,client可以在多個線程中被用來執(zhí)行多個方法。每次調(diào)用HttpClient.executeMethod() 方法,都會去鏈接管理器申請一個連接實例,申請成功這個鏈接實例被簽出(checkout),隨之在鏈接使用完后必須歸還管理器。管理器支持兩個設(shè)置:
          maxConnectionsPerHost 每個主機的最大并行鏈接數(shù),默認為2
          maxTotalConnections 客戶端總并行鏈接最大數(shù),默認為20

            管理器重新利用鏈接時,采取早歸還者先重用的方式(least recently used approach)。
            由于是使用HttpClient的程序而不是HttpClient本身來讀取應(yīng)答包的主體,所以HttpClient無法決定什么時間連接不再使用了,這也就要求在讀完應(yīng)答包的主體后必須手工顯式地調(diào)用releaseConnection()來釋放申請的鏈接。
          MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
          HttpClient client = new HttpClient(connectionManager);
          ...
          // 在某個線程中。
          GetMethod get = new GetMethod("http://jakarta.apache.org/");
          try {
          client.executeMethod(get);
          // print response to stdout
          System.out.println(get.getResponseBodyAsStream());
          } finally {
          // be sure the connection is released back to the connection
          // manager
          get.releaseConnection();
          }
          對每一個HttpClient.executeMethod須有一個method.releaseConnection()與之匹配.

          12、HTTP方法


            HttpClient支持的HTTP方法有8種,下面分述之。

            1、Options

            HTTP方法Options用來向服務(wù)器發(fā)送請求,希望獲得針對由請求URL(request url)標志的資源在請求/應(yīng)答的通信過程可以使用的功能選項。通過這個方法,客戶端可以在采取具體行動之前,就可對某一資源決定采取什么動作和/或以及一些必要條件,或者了解服務(wù)器提供的功能。這個方法最典型的應(yīng)用,就是用來獲取服務(wù)器支持哪些HTTP方法。
            HttpClient中有一個類叫OptionsMethod,來支持這個HTTP方法,利用這個類的getAllowedMethods方法,就可以很簡單地實現(xiàn)上述的典型應(yīng)用。
          OptionsMethod options = new OptionsMethod("http://jakarta.apache.org");
          // 執(zhí)行方法并做相應(yīng)的異常處理
          ...
          Enumeration allowedMethods = options.getAllowedMethods();
          options.releaseConnection();

            2、Get

             HTTP方法GET用來取回請求URI(request-URI)標志的任何信息(以實體(entity)的形式),"get"這個單詞本意就是”獲取“的意思。如果請求URI指向的一個數(shù)據(jù)處理過程,那這個過程生成的數(shù)據(jù),在應(yīng)答中以實體的形式被返回,而不是將這個過程的代碼的返回。
            如果HTTP包中含有If-ModifiedSince, If-Unmodified-Since, If-Match, If-None-Match, 或 If-Range等頭字段,則GET也就變成了”條件GET“,即只有滿足上述字段描述的條件的實體才被取回,這樣可以減少一些非必需的網(wǎng)絡(luò)傳輸,或者減少為獲取某一資源的多次請求(如第一次檢查,第二次下載)。(一般的瀏覽器,都有一個臨時目錄,用來緩存一些網(wǎng)頁信息,當再次瀏覽某個頁面的時候,只下載那些修改過的內(nèi)容,以加快瀏覽速度,就是這個道理。至于檢查,則常用比GET更好的方法HEAD來實現(xiàn)。)如果HTTP包中含有Range頭字段,那么請求URI指定的實體中,只有決定范圍條件的那部分才被取回來。(用過多線程下載工具的朋友,可能比較容易理解這一點)
            這個方法的典型應(yīng)用,用來從web服務(wù)器下載文檔。HttpClient定義了一個類叫GetMethod來支持這個方法,用GetMethod類中g(shù)etResponseBody, getResponseBodyAsStream 或 getResponseBodyAsString函數(shù)就可以取到應(yīng)答包包體中的文檔(如HTML頁面)信息。這這三個函數(shù)中,getResponseBodyAsStream通常是最好的方法,主要是因為它可以避免在處理下載的文檔之前緩存所有的下載的數(shù)據(jù)。
          GetMethod get = new GetMethod("http://jakarta.apache.org");
          // 執(zhí)行方法,并處理失敗的請求.
          ...
          InputStream in = get.getResponseBodyAsStream();
          // 利用輸入流來處理信息。
          get.releaseConnection();

            對GetMethod的最常見的不正確的使用,是沒有將全部的應(yīng)答主體的數(shù)據(jù)讀出來。還有,必須注意要手工明確地將鏈接釋放。

            3、Head

            HTTP的Head方法,與Get方法完全一致,唯一的差別是服務(wù)器不能在應(yīng)答包中包含主體(message-body),而且一定不能包含主體。使用這個方法,可以使得客戶無需將資源下載回就可就以得到一些關(guān)于它的基本信息。這個方法常用來檢查超鏈的可訪問性以及資源最近有沒有被修改。
            HTTP的head方法最典型的應(yīng)用,是獲取資源的基本信息。HttpClient定義了HeadMethod類支持這個方法,HeadMethod類與其它*Method類一樣,用 getResponseHeaders()取回頭部信息,而沒有自己的特殊方法。
          HeadMethod head = new HeadMethod("http://jakarta.apache.org");
          // 執(zhí)行方法,并處理失敗的請求.
          ...
          // 取回應(yīng)答包的頭字段信息.
          Header[] headers = head.getResponseHeaders(); // 只取回最后修改日期字段的信息.
          String lastModified = head.getResponseHeader("last-modified").getValue();


            4、Post

            Post在英文有“派駐”的意思,HTTP方法POST就是要求服務(wù)器接受請求包中的實體,并將其作為請求URI的下屬資源。從本質(zhì)上說,這意味著服務(wù)器要保存這個實體信息,而且通常由服務(wù)器端的程序進行處理。Post方法的設(shè)計意圖,是要以一種統(tǒng)一的方式實現(xiàn)下列功能:
          1. 對已有的資源做評注
          2. 將信息發(fā)布到BBS、新聞組、郵件列表,或類似的文章組中
          3. 將一塊數(shù)據(jù),提交給數(shù)據(jù)處理進程
          4. 通過追加操作,來擴展一個數(shù)據(jù)庫
            這些都操作期待著在服務(wù)器端產(chǎn)生一定的“副作用”,如修改了數(shù)據(jù)庫等。
            HttpClient定義PostMethod類以支持該HTTP方法,在httpclient中,使用post方法有兩個基本的步驟:為請求包準備數(shù)據(jù),然后讀取服務(wù)器來的應(yīng)答包的信息。通過調(diào)用 setRequestBody()函數(shù),來為請求包提供數(shù)據(jù),它可以接收三類參數(shù):輸入流、名值對數(shù)組或字符串。至于讀取應(yīng)答包需要調(diào)用 getResponseBody* 那一系列的方法,與GET方法處理應(yīng)答包的方法相同。
            常見問題是,沒有將全部應(yīng)答讀取(無論它對程序是否有用),或沒有釋放鏈接資源。

          posted on 2008-02-18 17:49 劉錚 閱讀(411) 評論(0)  編輯  收藏 所屬分類: JAVA General

          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計

          留言簿(1)

          文章分類(141)

          文章檔案(147)

          搜索

          最新評論

          主站蜘蛛池模板: 邢台县| 溧水县| 闸北区| 兴国县| 卓资县| 林西县| 崇义县| 开化县| 旺苍县| 大冶市| 通海县| 宁阳县| 华蓥市| 仲巴县| 阳新县| 页游| 昌江| 阿合奇县| 昭通市| 顺昌县| 江西省| 巧家县| 建湖县| 宁南县| 抚宁县| 三明市| 灵台县| 东城区| 沁水县| 汕尾市| 丹巴县| 朝阳区| 中宁县| 沽源县| 类乌齐县| 延安市| 普格县| 许昌市| 杭州市| 扎兰屯市| 高阳县|