淺談httpClient使用總結

      目前C/S仍是B/S結構的應用程序, HTTP 應該是最爲普遍使用的協議了。在 Java 平臺上,Java 標準庫提供了 一個HttpURLConnection 類來支持 HTTP 通信。不過 HttpURLConnection 自己的 API 不夠友好,所提供的功能也有限。httpClien是一個實現http協議不少操做功能的組件,而且它支持 HTTP 協議最新的版本和建議,如今Android已經成功的集成了HttpClient。另外,最新由Square 公司開源的 OkHttp 聽說能提供更高效率的http鏈接,支持GZIP 壓縮和 HTTP 響應緩存功能,在原理上應該是大同小異的。
      再說httpclient ,那也是眼花繚亂。隨便一搜,好比有些博文使用了 org.apache.commons.httpclient.HttpClient ,有些博文用org.apache.http.client.HttpClient 類。原來,httpclient原本是屬於apache-commons 項目下的一個子項目,後來是由Apache HttpComponents項目開發了後面的版本以提供更好的性能和更大的靈活性。commons下的這個httpclient最高版本是目前的3.1,支持HTTP協議1.1,繼承了java.net.urlConnection,已經足夠提供目前測試的大部分rest服務接口,本文介紹一下用法。這裏能夠查看全部的API -  http://hc.apache.org/httpclient-3.x/apidocs/overview-summary.html  
   在金融產品的測試過程當中,我曾經碰到的服務接口有區分,好比與合做方交互通常是傳xml較多,單應用的後臺通常是http rest服務。這裏提供一個傳json的例子。
public void urlPostJson(String url,String desc,String json) {
        log.info("-----------------------------"+desc+"  Request: " + json);
        HttpClient client = new HttpClient();
        client.getHostConfiguration().setProxy("127.0.0.1", 5689);
        client.getHttpConnectionManager().getParams().setConnectionTimeout(3000);//        client.setConnectionTimeout(3000);
        client.getParams().setSoTimeout(3000);//        client.setTimeout(1000);
        client.getParams().setConnectionManagerTimeout(1000);
        PostMethod method = new PostMethod(url);
        try {
//            method.setRequestHeader("Content-Type", " application/json; charset=UTF-8");
            method.setRequestBody(new ByteArrayInputStream(json.getBytes("UTF-8")));
//            method.setRequestBody(json);
            int status = client.executeMethod(method);
            String res=method.getResponseBodyAsString();
            log.info("                               status:"+status+"  Resonse: "+res);
        } catch (IOException e) {
            log.error("HttpClient.executeMethod(postMethod) IOException!",e);
        }finally{
            if (method != null) {
                method.releaseConnection();
            }
        }
    }
如上,利用httpclient去訪問接口的步驟通常是:

1. 建立HttpClient對象。2. 構造Http 請求對象。3. 執行HttpClient對象的execute方法,將Http請求對象做爲該方法的參數。4. 讀取execute方法返回的HttpResponse結果並解析。五、釋放鏈接。整個過程是否是與咱們平時在瀏覽器上訪問相似呢。惟一區別是不能執行HTTP頁面中籤入嵌入的JS代碼,天然也不會對頁面內容進行任何解析、處理,這些都是須要開發人員來完成的。在以上代碼中,httpclient的初始化沒有看到任何參數設置,實際上是在它的構造函數裏調用了接口,並設置了默認值,以下包含協議版本、客戶端引擎、cookie策略等,若是要本身設置,能夠經過它的成員變量httpClientParams對象進行設置。html

一、關於重定向。
 http多種狀態已經在HttpStatus這個類中定義好,其中重定向 根據RFC2616中對自動轉向的定義,主要有兩種:301和302。301表示永久的移走(Moved Permanently),當返回的是301,則表示請求的資源已經被移到一個固定的新地方,任何向該地址發起請求都會被轉到新的地址上。302表示暫時的轉向,好比在服務器端的servlet程序調用了sendRedirect方法,則在客戶端就會獲得一個302的代碼,這時服務器返回的頭信息中location的值就是sendRedirect轉向的目標地址。若是是get方式請求,httpclient是自動幫你重定向並拿到響應信息,也能夠經過設置 method . setFollowRedirects ( false )不自動轉。post的請求是不能自動跳轉的,須要從頭部信息中拿到Location(多是相對路徑)所以須要對location返回的值作一些處理才能夠發起向新地址的請求。
二、字符編碼
客戶端發送的數據多樣,最終全部數據都是經過最底層的物理層面的電信號來傳遞,首部字段content-type 說明了實體主體內對象的媒體類型,即服務器經過contentType來知道這個是什麼樣子的數據。客戶端在拿到服務器返回的數據後,根據頭部設置的可接收媒體類型進行內容協商,返回最適合的資源。對於有中文的請求,爲避免出現亂碼,最好設置content-type。在上部分的代碼截圖,你們能夠看到,若是咱們本身不設置contentType 那麼默認會採用ISO的方式進行傳輸,那麼若是與你實際的編碼方式不一致的話,服務器就會拿到一個亂碼,從而沒法正常的響應。能夠經過上面代碼進行設置,也能夠經過 method.setRequestHeader("Content-Type", " application/json; charset=UTF-8")來進行設置
 
三、cookie
httpclient默認的cookie策略是 RFC_2109其中能夠經過去更改。請求過程當中能夠經過sendHead 把cookie放入頭部,並傳到後端進行訪問。
 
總結:
基本上使用httpclient過程當中,主要操做的類有:httpclient,getMethod,postMethod,httpClientParams,httpConnectionManager這幾個。詳見如下的類圖。
 HttpClient表明了一個http的客戶端,HttpConnectionManager是用來管理HttpConnection 的,HttpConnection表明了一個http鏈接,因此HttpConnectionManager其實質上也就是一個http鏈接池,管理這些 http鏈接(和數據庫鏈接池一個道理)。HttpMethod表明了一個Http方法,一個HttpClient能夠運行多個HttpMethod(實 質上,httpclient執行一個HttpMethod時,會從connectionmanager那裏獲取一個httpconnection,在此 connection上執行該method,執行完該method後,讓method 釋放該httpconnection,從而將該httpconnection返回給connectionmanager,以便供後續的method使 用) 因此在httpclient鏈接後資源釋放問題很重要,就跟咱們用database connection要釋放資源同樣。 
 
四、小tips
一、fidder做爲一款強大好用的web調試利器,針對commons下的httpclient能夠以下設置代理,能幫你記錄下請求和響應的全部信息。 接口測試中遇到異常方便查看,減小本身debug的狀況。
 
 
五、擴展
 
httpclient功能之強大,不是一篇文章可以說完。其餘的,例如文件上傳、DNS配置、多線程下的httpclient使用。過程當中須要你對http協議、cookie-session機制有必定的認識基礎。本篇文件旨在用作一些簡單接口的測試,目前commons這個版本已經不作更新了,若是有更復雜的接口,仍是推薦使用org.apache.http.impl.client下的httpclient。
相關文章
相關標籤/搜索