1. 程式人生 > >Android學習筆記----HttpURLConnection 和 HttpClient(已經被廢棄)

Android學習筆記----HttpURLConnection 和 HttpClient(已經被廢棄)

/***************************************************************/ 使用 HTTP 協議訪問網路 在 Android 上傳送 HTTP 請求的方式一般有兩種, HttpURLConnection 和 HttpClient. HttpURLConnection
首先需要獲取到 HttpURLConnection 的例項,一般只需 new 出一個 URL 物件,並傳入目標的網路地址,然後呼叫一下 openConnection()方法即可。
HttpURLConnection connection = (HttpURLConnection) url.openConnection();


注意:如果URL傳入的地址中含有中文要對含有的中文進行URL編碼,然後再拼接成地址,否則傳遞資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(中文);
得到了 HttpURLConnection 的例項之後,我們可以設定一下 HTTP 請求所使用的方法。常用的方法主要有兩個, GET 和 POST。  GET 表示希望從伺服器那裡獲取資料     POST 則表示希望提交資料給伺服器 connection.setRequestMethod("GET"); 注意:其實GET方式也可以向伺服器提交資料,如何通過GET方式提交資料,見最後GET方式提交資料
接下來就可以進行一些自由的定製了,比如設定連線超時讀取超時的毫秒數,以及伺服器希望得到的一些訊息頭等。這部分內容根據自己的實際情況進行編寫 connection.setConnectTimeout(8000); //設定連線超時 connection.setReadTimeout(8000);    //讀取超時的毫秒數 獲取連線狀態碼,如果狀態碼為200則表示連線成功 int status_code = connection.getResponseCode(); if(code == 200){ .........................................................................................
}
之後再呼叫 getInputStream()方法就可以獲取到伺服器返回的輸入流了 InputStream in = connection.getInputStream();//獲取到伺服器返回的輸入流了 剩下的任務就是對輸入流進行讀取,然後進行相關處理
public class StreamTool {
    /**
     * 把一個inputstream裡面的內容轉化成一個byte[]
     */
    public static byte[] getBytes(InputStream is) throws Exception{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = is.read(buffer))!=-1){
            bos.write(buffer, 0, len);
        }
        is.close();
        bos.flush();
        byte[] result = bos.toByteArray();
        return  result;
    }
}

byte[] result = StreamTool.getBytes(in);
//如果讀取的是圖片資料
Bitmap bitmap = BitmapFactory.decodeByteArray(result,0,result.length);//也可以直接用Bitmap bitmap = BitmapFactory.decodeStream(in);
......
//如果讀取的是網頁資料,此處要注意網頁的編碼問題
String temp = new String(result);
if (temp.contains("gbk")) {
    String temp = new String(result, "gb2312");
    .......................
} else {
    .......................
}
最後需要呼叫 disconnect()方法將這個 HTTP 連線關閉掉 connection.disconnect(); 例項:
private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
    switch (msg.what) {
        case SHOW_RESPONSE:
        String response = (String) msg.obj;
        // 在這裡進行UI操作,將結果顯示到介面上

    }
  }
};

new Thread(new Runnable() {
@Override
public void run() {
        HttpURLConnection connection = null;
        try {
            URL url = new URL("http://www.baidu.com");
            connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("GET");

            connection.setConnectTimeout(8000);
            connection.setReadTimeout(8000);

            InputStream in = connection.getInputStream();
            // 下面對獲取到的輸入流進行讀取
            BufferedReader reader = new BufferedReader(new  InputStreamReader(in));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            Message message = new Message();
            message.what = SHOW_RESPONSE;
            // 將伺服器返回的結果存放到Message中
            message.obj = response.toString();
            handler.sendMessage(message);
        } catch (Exception e) {

            e.printStackTrace();

        } finally {
                if (connection != null) {
                    connection.disconnect();
                }
        }
    }
}).start();

提交資料給伺服器 將 HTTP 請求的方法改成 POST,並在獲取輸入流之前把要提交的資料寫出即可。注意每條資料都要以鍵值對的形式存在,資料與資料之間用&符號隔開,比如說我們想要向伺服器提交使用者名稱和密碼,就可以這樣寫:
<span style="font-size:18px;">connection.setRequestMethod("POST");//設定為POST方式
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");//向伺服器提交資料
int code = conn.getResponseCode();//獲取伺服器返回的狀態碼,以此來判斷資料是否提交成功
if(code==200){
    //資料提交成功,獲取伺服器返回的資料
    InputStream in = conn.getInputStream();
    byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(is)是自定義的流處理方法,見第一段例項程式碼
    ........................................................................
}</span>

注意:如果傳入的地址中含有中文要對中文進行URL編碼,然後再拼接成地址,否則傳遞資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(中文引數); 同時如果要提交的資料中含有中文要對提交的中文資料進行URL編碼,否則傳輸資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(“張三”); out.writeBytes("username= "+ param1+ " &password=123456");//對於英文或者數字,進不進行URL編碼應該沒有什麼影響
!!!!!!!HttpClient!!!!!!已經被廢棄掉了
HttpClient HttpClient 是一個介面,因此無法建立它的例項,通常情況下都會建立一個 DefaultHttpClient 的例項 HttpClient httpClient = new DefaultHttpClient(); 接下來如果想要發起一條 GET 請求,就可以建立一個 HttpGet 物件,並傳入目標的網路地址,然後呼叫 HttpClient 的 execute()方法即可: HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet); 注意:如果傳入的地址引數中含有中文要對中文引數進行URL編碼,然後再拼接成地址,否則傳遞資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(中文引數); 執行 execute()方法之後會返回一個 HttpResponse 物件,伺服器所返回的所有資訊就會包含在這裡面。通常情況下我們都會先取出伺服器返回的狀態碼,如果等於 200 就說明請求和響應都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) { // 請求和響應都成功了 } 接下來在這個 if 判斷的內部取出服務返回的具體內容,可以呼叫 getEntity()方法獲取到一個 HttpEntity 例項,然後再用 EntityUtils.toString()這個靜態方法將 HttpEntity 轉換成字串即可(也可以呼叫entity的getContent()例項方法,得到輸入流),如下所示: HttpEntity entity = httpResponse.getEntity();  String response = EntityUtils.toString(entity);
或者 HttpEntity entity = httpResponse.getEntity();  InputStream in    = entity.getContent(); byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(in)是自定義的流處理方法,見第一段例項程式碼 注意如果伺服器返回的資料是帶有中文的,直接呼叫 EntityUtils.toString()方法進行轉換會有亂碼的情況出現,這個時候只需要在轉換的時候將字符集指定成 utf-8 就可以了,如下所示: String response = EntityUtils.toString(entity, "utf-8"); 例項:
<span style="font-size:18px;">private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SHOW_RESPONSE:
                String response = (String) msg.obj;
                // 在這裡進行UI操作,將結果顯示到介面上

        }
    }
};
new Thread(new Runnable() {
        @Override
        public void run() {
           try {
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet("http://www.baidu.com");
                    HttpResponse httpResponse = httpClient.execute(httpGet);
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        // 請求和響應都成功了
                        HttpEntity entity = httpResponse.getEntity();
                        String response = EntityUtils.toString(entity,"utf-8");
                        Message message = new Message();
                        message.what = SHOW_RESPONSE;
                        // 將伺服器返回的結果存放到Message中
                        message.obj = response.toString();
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
      }
}).start();</span>


提交資料給伺服器 建立一個 DefaultHttpClient 的例項 HttpClient httpClient = new DefaultHttpClient();
建立一個 HttpPost 物件,並傳入目標的網路地址,如下所示: HttpPost httpPost = new HttpPost("http://www.baidu.com"); 注意:如果傳入的地址引數中含有中文要對中文引數進行URL編碼,然後再拼接成地址,否則傳遞資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(中文引數);
然後通過一個 NameValuePair 集合來存放待提交的引數,並將這個引數集合傳入到一個UrlEncodedFormEntity 中,然後呼叫 HttpPost 的 setEntity()方法將構建好的 UrlEncodedFormEntity傳入,如下所示:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);


注意:如果要提交的資料中含有中文要對提交的中文資料進行URL編碼,否則傳輸資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(“張三”); params.add(new BasicNameValuePair("username", param1));
接下來的操作就和 HttpGet 一樣了,呼叫 HttpClient 的 execute()方法,並將 HttpPost 物件傳入即可: HttpResponse  httpResponse = httpClient.execute(httpPost); 執行 execute()方法之後會返回一個 HttpResponse 物件,伺服器所返回的所有資訊就會包含在這裡面。通常情況下我們都會先取出伺服器返回的狀態碼,如果等於 200 就說明請求和響應都成功了,如下所示:
<span style="font-size:18px;">if (httpResponse.getStatusLine().getStatusCode() == 200) {
   // 請求和響應都成功,接下來可以獲取伺服器的返回資料
     HttpEntity entity = httpResponse.getEntity(); 
     String response = EntityUtils.toString(entity);
   或者
     HttpEntity entity = httpResponse.getEntity(); 
     String response = EntityUtils.toString(entity, "utf-8");//這樣可以防止亂碼問題
   或者
    HttpEntity entity = httpResponse.getEntity(); 
    InputStream in    = entity.getContent();
    byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定義的流處理方法,見第一段例項程式碼
    .........................................................................
}</span>


/***************************************************************/ GET方式提交資料 HttpURLConnection的GET方式:
<span style="font-size: 14px;"> </span><span style="font-size:18px;"> String path = "提交資料的伺服器的地址";
  String param1 = URLEncoder.encode(name);               //對要傳遞的資料進行URL編碼,防止出現亂碼問題
  String param2 = URLEncoder.encode(password);       //對要傳遞的資料進行URL編碼,防止出現亂碼問題
  URL url = new URL(path + "?name=" + param1 + "&password=" + param2);//如果path中含有中文引數的話,也要對path進行URL編碼
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setRequestMethod("GET");
  conn.setReadTimeout(5000);
  // 只有呼叫getInputStream()方法的時候,資料才會被提交到伺服器。
  // 獲取伺服器返回的流資訊
  InputStream is = conn.getInputStream();
  byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定義的流處理方法,見第一段例項程式碼
  .........................................................................
</span>


HttpClient的GET方式:
 //1. 獲取到一個瀏覽器的例項
  HttpClient client = new DefaultHttpClient();
  //2. 準備請求的地址
  String param1 = URLEncoder.encode(name);                   //對要傳遞的資料進行URL編碼,防止出現亂碼問題
  String param2 = URLEncoder.encode(password);            //對要傳遞的資料進行URL編碼,防止出現亂碼問題
  HttpGet httpGet = new HttpGet(path + "?name=" + param1 + "&password=" + param2); //如果path中含有中文引數的話,也要對path進行URL編碼
 
  //3. 敲回車 發請求
  HttpResponse  ressponse = client.execute(httpGet);
  int code = ressponse.getStatusLine().getStatusCode();
  if(code == 200){
       InputStream is  =ressponse.getEntity().getContent();
       byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定義的流處理方法,見第一段例項程式碼
       .....................................................................
  }
  else{
     .....................................................................
  }



POST方式跟GET方式提交資料到伺服器的區別: get 一次提交的資料資料量比較小 4K 內部其實通過組拼url的方式 post 可以提交比較大的資料 form表單的形式 流的方式寫到伺服器 補充: 為了防止伺服器端接收到的中文字元是亂碼,在伺服器端接收到的資料要注意編碼問題。
 String name = request.getParameter("name");
  if(name!=null){
      name =	new String( name.getBytes("iso8859-1"),"utf-8");
  }

伺服器端對接收的位元組流,按照"iso8859-1"進行編碼生成字串所以對接收到的字串,要按"iso8859-1"反編碼成位元組陣列,再按UTF-8重新進行編碼,生成中文字元。