Android學習筆記----HttpURLConnection 和 HttpClient(已經被廢棄)
阿新 • • 發佈:2019-02-12
/***************************************************************/
使用 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();//獲取到伺服器返回的輸入流了
剩下的任務就是對輸入流進行讀取,然後進行相關處理
提交資料給伺服器 將 HTTP 請求的方法改成 POST,並在獲取輸入流之前把要提交的資料寫出即可。注意每條資料都要以鍵值對的形式存在,資料與資料之間用&符號隔開,比如說我們想要向伺服器提交使用者名稱和密碼,就可以這樣寫:
注意:如果傳入的地址中含有中文,要對中文進行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"); 例項:
提交資料給伺服器 建立一個 DefaultHttpClient 的例項 HttpClient httpClient = new DefaultHttpClient();
建立一個 HttpPost 物件,並傳入目標的網路地址,如下所示: HttpPost httpPost = new HttpPost("http://www.baidu.com"); 注意:如果傳入的地址引數中含有中文,要對中文引數進行URL編碼,然後再拼接成地址,否則傳遞資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(中文引數);
然後通過一個 NameValuePair 集合來存放待提交的引數,並將這個引數集合傳入到一個UrlEncodedFormEntity 中,然後呼叫 HttpPost 的 setEntity()方法將構建好的 UrlEncodedFormEntity傳入,如下所示:
注意:如果要提交的資料中含有中文,要對提交的中文資料進行URL編碼,否則傳輸資料會出現中文亂碼問題,解決方式如下: String param1 = URLEncoder.encode(“張三”); params.add(new BasicNameValuePair("username", param1));
接下來的操作就和 HttpGet 一樣了,呼叫 HttpClient 的 execute()方法,並將 HttpPost 物件傳入即可: HttpResponse httpResponse = httpClient.execute(httpPost); 執行 execute()方法之後會返回一個 HttpResponse 物件,伺服器所返回的所有資訊就會包含在這裡面。通常情況下我們都會先取出伺服器返回的狀態碼,如果等於 200 就說明請求和響應都成功了,如下所示:
/***************************************************************/ GET方式提交資料 HttpURLConnection的GET方式:
HttpClient的GET方式:
POST方式跟GET方式提交資料到伺服器的區別: get 一次提交的資料資料量比較小 4K 內部其實通過組拼url的方式 post 可以提交比較大的資料 form表單的形式 流的方式寫到伺服器 補充: 為了防止伺服器端接收到的中文字元是亂碼,在伺服器端接收到的資料要注意編碼問題。
伺服器端對接收的位元組流,按照"iso8859-1"進行編碼生成字串,所以對接收到的字串,要按"iso8859-1"反編碼成位元組陣列,再按UTF-8重新進行編碼,生成中文字元。
首先需要獲取到 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方式提交資料
}
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重新進行編碼,生成中文字元。