Android--Apache HttpClient

來源:互聯網
上載者:User

標籤:

上一篇文章介紹了使用HttpURLConnection來完成對於HTTP協議的支援。現在介紹一個新的方式來訪問Web網站,那就是HttpClient。

  HttpClient是Apache開源組織提供的一個開源的項目,從名字上就可以看出,它是一個簡單的HTTP用戶端(並不是瀏覽器),可以發送HTTP請求,接受HTTP響應。但是不會快取服務器的響應,不能執行HTTP頁面中籤入嵌入的JS代碼,自然也不會對頁面內容進行任何解析、處理,這些都是需要開發人員來完成的。

  現在Android已經成功整合了HttpClient,所以開發人員在Android項目中可以直接使用HttpClient來想Web網站提交請求以及接受響應,如果使用其他的Java項目,需要引入進相應的Jar包。HttpClient可以在官網上下載。

  

HttpClient

  HttpClient其實是一個interface類型,HttpClient封裝了對象需要執行的Http請求、身分識別驗證、串連管理和其它特性。從文檔上看,HttpClient有三個已知的實作類別分別是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,會發現有一個專門為Android應用準備的實作類別AndroidHttpClient,當然使用常規的DefaultHttpClient也可以實現功能,但是既然開發的是Android應用程式,還是使用Android專有的實作類別,一定有其優勢。

  從兩個類包所有在位置就可以看出區別,AndroidHttpClient定義在android.net.http.AndroidHttpClient包下,屬於Android原生的http訪問,而DefaultHttpClient定義在org.apache.http.impl.client.DefaultHttpClient包下,屬於對apche項目的支援。而AndroidHttpClient沒有公開的建構函式,只能通過靜態方法newInstance()方法來獲得AndroidHttpClient對象。

  AndroidHttpClient對於DefaultHttpClient做了一些改進,使其更使用用於Android項目:

  1. 關掉到期檢查,自串連可以打破所有的時間限制。
  2. 可以設定ConnectionTimeOut(連線逾時)和SoTimeout(讀取資料逾時)。
  3. 關掉重新導向。
  4. 使用一個Session緩衝用於SSL Sockets。
  5. 如果伺服器支援,使用gzip壓縮方式用於在服務端和用戶端傳遞的資料。
  6. 預設情況下不保留Cookie。    

  簡單來說,用HttpClient發送請求、接收響應都很簡單,只需要幾個步驟即可:

  1. 建立HttpClient對象。
  2. 建立對應的發送請求的對象,如果需要發送GET請求,則建立HttpGet對象,如果需要發送POST請求,則建立HttpPost對象。
  3. 對於發送請求的參數,GET和POST使用的方式不同,GET方式可以使用拼接字串的方式,把參數拼接在URL結尾;POST方式需要使用setEntity(HttpEntity entity)方法來佈建要求參數。
  4. 調用HttpClient對象的execute(HttpUriRequest request)發送請求,執行該方法返回一個HttpResponse對象。
  5. 調用HttpResponse的對應方法擷取伺服器的回應標頭、響應內容等。

DefaultHttpClient

  先看看使用DefaultHttpClient方式發送Web網站請求,上面已經簡要說明了步驟,在這裡簡要說明一個參數的傳遞問題,對於GET方式,只需要拼接字串就在URL結尾即可,但是對於POST方式,需要傳遞HttpEntity對象,HttpEntity為一個介面,有多個實作類別,可以使用其間接子繼承,UrlEncodedFormEntity類來儲存請求參數,並傳遞給HttpPost。

  此例子簡單實現了在Android用戶端使用DefaultHttpClient實現一個Http網站登陸的實現,使用的是POST傳遞,其傳遞值只需要傳遞username+password即可,當傳遞的資料為admin+123則認為登陸成功。Web網站使用.net的架構,一個一般處理常式,簡單的比對賬戶密碼,這裡就不在此講解。

  因為Android4.0之後對使用網路有特殊要求,已經無法再在主線程中訪問網路了,必須使用多線程訪問的模式,其他的一些資訊在代碼注釋中已經說明。

 DefaultHttpClient-Code

  1 package com.bgxt.httpUtils;  2   3 import java.io.ByteArrayOutputStream;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.UnsupportedEncodingException;  7 import java.util.ArrayList;  8 import java.util.HashMap;  9 import java.util.List; 10 import java.util.Map; 11  12 import org.apache.http.HttpResponse; 13 import org.apache.http.NameValuePair; 14 import org.apache.http.client.ClientProtocolException; 15 import org.apache.http.client.entity.UrlEncodedFormEntity; 16 import org.apache.http.client.methods.HttpPost; 17 import org.apache.http.impl.client.DefaultHttpClient; 18 import org.apache.http.message.BasicNameValuePair; 19  20 public class httpClientUtils implements Runnable { 21     /** 22      * 對於Android4.0之上的環境下,不能在主線程中訪問網路 所以這裡另建立了一個實現了Runnable介面的Http訪問類 23      */ 24     private String username; 25     private String password; 26  27     public httpClientUtils(String username, String password) { 28         // 初始化使用者名稱和密碼 29         this.username = username; 30         this.password = password; 31     } 32  33     @Override 34     public void run() { 35         // 設定訪問的Web網站 36         String path = "http://192.168.1.103:1231/loginas.ashx"; 37         // 設定Http請求參數 38         Map<String, String> params = new HashMap<String, String>(); 39         params.put("username", username); 40         params.put("password", password); 41  42         String result = sendHttpClientPost(path, params, "utf-8"); 43         // 把返回的介面輸出 44         System.out.println(result); 45     } 46  47     /** 48      * 發送Http請求到Web網站 49      *  50      * @param path 51      *            Web網站請求地址 52      * @param map 53      *            Http請求參數 54      * @param encode 55      *            編碼格式 56      * @return Web網站響應的字串 57      */ 58     private String sendHttpClientPost(String path, Map<String, String> map, 59             String encode) { 60         List<NameValuePair> list = new ArrayList<NameValuePair>(); 61         if (map != null && !map.isEmpty()) { 62             for (Map.Entry<String, String> entry : map.entrySet()) { 63                 // 解析Map傳遞的參數,使用一個索引值對對象BasicNameValuePair儲存。 64                 list.add(new BasicNameValuePair(entry.getKey(), entry 65                         .getValue())); 66             } 67         } 68         try { 69             // 實現將請求 的參數封裝封裝到HttpEntity中。 70             UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode); 71             // 使用HttpPost請求方式 72             HttpPost httpPost = new HttpPost(path); 73             // 佈建要求參數到Form中。 74             httpPost.setEntity(entity); 75             // 執行個體化一個預設的Http用戶端 76             DefaultHttpClient client = new DefaultHttpClient(); 77             // 執行請求,並獲得響應資料 78             HttpResponse httpResponse = client.execute(httpPost); 79             // 判斷是否請求成功,為200時表示成功,其他均問有問題。 80             if (httpResponse.getStatusLine().getStatusCode() == 200) { 81                 // 通過HttpEntity獲得響應流 82                 InputStream inputStream = httpResponse.getEntity().getContent(); 83                 return changeInputStream(inputStream, encode); 84             } 85         } catch (UnsupportedEncodingException e) { 86             e.printStackTrace(); 87         } catch (ClientProtocolException e) { 88             e.printStackTrace(); 89         } catch (IOException e) { 90             e.printStackTrace(); 91         } 92         return ""; 93     } 94  95     /** 96      * 把Web網站返回的響應流轉換為字串格式 97      *  98      * @param inputStream 99      *            響應流100      * @param encode101      *            編碼格式102      * @return 轉換後的字串103      */104     private String changeInputStream(InputStream inputStream, String encode) {105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();106         byte[] data = new byte[1024];107         int len = 0;108         String result = "";109         if (inputStream != null) {110             try {111                 while ((len = inputStream.read(data)) != -1) {112                     outputStream.write(data, 0, len);113                 }114                 result = new String(outputStream.toByteArray(), encode);115 116             } catch (IOException e) {117                 e.printStackTrace();118             }119         }120         return result;121     }122 123 }

AndroidHttpClient

  使用AndroidHttpClient的方式和DefaultHttpClient差不多,不多的幾點區別上面已經說明,但是在此例子中沒有體現。有一點需要注意的是,AndroidHttpClient是一個final類,也沒有公開的建構函式,所以無法使用new的形式對其進行執行個體化,必須使用AndroidHttpClient.newInstance()方法獲得AndroidHttpClient對象。

  樣本中依然是使用POST請求,實現的功能和DefaultHttpClient樣本一樣。細節部分已經在注釋中體現,直接看代碼即可。

  1 package com.bgxt.httpUtils;  2   3 import java.io.ByteArrayOutputStream;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.UnsupportedEncodingException;  7 import java.util.ArrayList;  8 import java.util.HashMap;  9 import java.util.List; 10 import java.util.Map; 11  12 import org.apache.http.HttpResponse; 13 import org.apache.http.NameValuePair; 14 import org.apache.http.client.ClientProtocolException; 15 import org.apache.http.client.HttpClient; 16 import org.apache.http.client.entity.UrlEncodedFormEntity; 17 import org.apache.http.client.methods.HttpPost; 18 import org.apache.http.impl.client.DefaultHttpClient; 19 import org.apache.http.message.BasicNameValuePair; 20  21 import android.net.http.AndroidHttpClient; 22  23 public class AndroidHttpClientUtils implements Runnable { 24  25     private String username; 26     private String password; 27  28     public AndroidHttpClientUtils(String username, String password) { 29         // 初始化使用者名稱和密碼 30         this.username = username; 31         this.password = password; 32     } 33  34     @Override 35     public void run() { 36         // 設定訪問的Web網站 37         String path = "http://192.168.1.103:1231/loginas.ashx"; 38         //設定Http請求參數 39         Map<String, String> params = new HashMap<String, String>(); 40         params.put("username", username); 41         params.put("password", password); 42  43         String result = sendHttpClientPost(path, params, "utf-8"); 44         //把返回的介面輸出 45         System.out.println(result); 46     } 47     /** 48      * 發送Http請求到Web網站 49      * @param path Web網站請求地址 50      * @param map Http請求參數 51      * @param encode 編碼格式 52      * @return Web網站響應的字串 53      */ 54     private String sendHttpClientPost(String path,Map<String, String> map,String encode) 55     { 56         List<NameValuePair> list=new ArrayList<NameValuePair>(); 57         if(map!=null&&!map.isEmpty()) 58         { 59             for(Map.Entry<String, String> entry:map.entrySet()) 60             { 61                 //解析Map傳遞的參數,使用一個索引值對對象BasicNameValuePair儲存。 62                 list.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); 63             } 64         } 65         try { 66             //實現將請求 的參數封裝封裝到HttpEntity中。 67             UrlEncodedFormEntity entity=new UrlEncodedFormEntity(list, encode); 68             //使用HttpPost請求方式 69             HttpPost httpPost=new HttpPost(path); 70             //佈建要求參數到Form中。 71             httpPost.setEntity(entity); 72             //執行個體化一個預設的Http用戶端,使用的是AndroidHttpClient 73             HttpClient client=AndroidHttpClient.newInstance(""); 74             //執行請求,並獲得響應資料 75             HttpResponse httpResponse= client.execute(httpPost); 76             //判斷是否請求成功,為200時表示成功,其他均問有問題。 77             if(httpResponse.getStatusLine().getStatusCode()==200) 78             { 79                 //通過HttpEntity獲得響應流 80                 InputStream inputStream=httpResponse.getEntity().getContent(); 81                 return changeInputStream(inputStream,encode); 82             } 83              84         } catch (UnsupportedEncodingException e) { 85             // TODO Auto-generated catch block 86             e.printStackTrace(); 87         } catch (ClientProtocolException e) { 88             // TODO Auto-generated catch block 89             e.printStackTrace(); 90         } catch (IOException e) { 91             // TODO Auto-generated catch block 92             e.printStackTrace(); 93         } 94          95         return ""; 96     }                     97     /** 98      * 把Web網站返回的響應流轉換為字串格式 99      * @param inputStream 響應流100      * @param encode 編碼格式101      * @return 轉換後的字串102      */103     private  String changeInputStream(InputStream inputStream,104             String encode) { 105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();106         byte[] data = new byte[1024];107         int len = 0;108         String result="";109         if (inputStream != null) {110             try {111                 while ((len = inputStream.read(data)) != -1) {112                     outputStream.write(data,0,len);                    113                 }114                 result=new String(outputStream.toByteArray(),encode);115                 116             } catch (IOException e) {117                 e.printStackTrace();118             }119         }120         return result;121     }122 }

Android--Apache HttpClient

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.