您的位置:首页 > 理论基础 > 计算机网络

Android网络编程之HttpUrlConnection、HttpClient

2017-02-10 13:49 573 查看
这篇文章我们共同来学习HttpUrlConnection以及HttpClient.

首先,我们来了解一下通过Http协议,Android APP客户端与服务器交互的基本知识



客户端->服务器:客户端向服务器发送请求主要包含以下信息:请求的Url地址、请求头以及可选的请求体

服务器->客户端:服务器接收到客户端发来的请求后,会进行相应的处理,并向客户端输出信息,输出的信息包含响应头和响应体。

Http协议支持的操作有GET、POST、HEAD、PUT、TRACE、OPTIONS、DELETE,其中最常用的还是GET和POST。

GET vs POST

GET:

1、GET请求可以被缓存

2、当用GET请求发送键值对时,键值对会随着URL一起发送的

3、GET请求的安全性很低,不能用GET请求发送敏感的信息

4、GET请求发送数据是有长度限制的(URL不能超过2048个字符) 

5、由于GET请求较低的安全性,我们不应该用GET请求去执行增加、删除、修改等操作,应该只用它来获取数据

POST:

1、POST请求从不会被缓存

2、POST请求的URL中追加键值对参数,这些键值对参数不是随着URL发送的,而是被放入到请求体中发送的

3、应该用POST请求发送敏感信息,而不是用GET

4、理论上POST请求不存在发送数据大小的限制

5、当执行增加、删除、修改等操作时,应该使用POST请求,而不应该使用GET请求

HttpURLConnection vs HttpClient

在Android 2.2版本以及之前的版本使用HttpClient是较好的选择,而在Android 2.3版本以及以后的版本,HttpURLConnection则是最佳的选择。

原因:Android 2.2之前(包括2.2),HttpURLConnection一直存在着一些令人厌烦的bug。而HttpClient是Apache用于发送http请求的客户端,其提供了强大的API支持,而且基本没有什么bug。

Android 2.2之后,HttpURLConnection的bug得到解决,并且其API简单,体积较小,也能够满足大部分的需求,因此非常适合Android项目。相反,HttpClient由于其太过复杂,Android团队在保持向后兼容的情况下,很难对其进行增强,另外从Android 6.0版本开始,HttpClient库被移除了。

HttpURLConnection使用

GET方
11810
式:

private HttpURLConnection getHttpURLConnection(String url) {
HttpURLConnection httpURLConnection = null;
try {
URL mUrl = new URL(url);
httpURLConnection = (HttpURLConnection) mUrl.openConnection();
httpURLConnection.setConnectTimeout(15000);  //设置连接超时时间
httpURLConnection.setReadTimeout(15000);  //设置读取超时时间
httpURLConnection.setRequestMethod("GET");  //设置请求参数,也可以不设置,默认为GET
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");  //添加Header
httpURLConnection.setDoInput(true);  //接收输入流。httpURLConnection默认也支持从服务端读取结果流,所以此设置也可以省略
httpURLConnection.setDoOutput(true);
} catch (IOException e) {
e.printStackTrace();
}
return httpURLConnection;
}

public void useHttpUrlConnectionGet(String url)
{
InputStream inputStream = null;
HttpURLConnection httpURLConnection = getHttpURLConnection(url);
try {
httpURLConnection.connect();  //通过调用connect方法建立TCP连接,但是并未真正获取数据。该方法也不必显式调用,当调用getInputStream方法时内部也会自动调用connect方法的
inputStream = httpURLConnection.getInputStream();  //调用getInputStream方法后,服务端才会收到请求,并阻塞式地接收服务端返回的数据
int code = httpURLConnection.getResponseCode();
String response = converStreamToString(inputStream);
Log.i("Debug", "请求状态码:" + code + "\n请求结果\n" + response);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

private String converStreamToString(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = null;
while((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
String response = sb.toString();
return response;
}


POST方式:

private HttpURLConnection getHttpURLConnection(String url) {
HttpURLConnection httpURLConnection = null;
try {
URL mUrl = new URL(url);
httpURLConnection = (HttpURLConnection) mUrl.openConnection();
httpURLConnection.setConnectTimeout(15000);  //设置连接超时时间
httpURLConnection.setReadTimeout(15000);  //设置读取超时时间
httpURLConnection.setRequestMethod("POST");  //设置请求参数
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");  //添加Header
httpURLConnection.setDoInput(true);  //接收输入流。httpURLConnection默认也支持从服务端读取结果流,所以此设置也可以省略
httpURLConnection.setDoOutput(true);
} catch (IOException e) {
e.printStackTrace();
}
return httpURLConnection;
}

private void postParams(OutputStream outputStream, List<NameValuePair>paramsList) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
for (NameValuePair pair:paramsList) {
if (!TextUtils.isEmpty(stringBuilder))
{
stringBuilder.append("&");
}
stringBuilder.append(URLEncoder.encode(pair.getName(), "UTF-8"));
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(stringBuilder.toString());
writer.flush();
writer.close();
}

private String converStreamToString(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = null;
while((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
String response = sb.toString();
return response;
}

public void useHttpUrlConnectionPost(String url)
{
InputStream inputStream = null;
HttpURLConnection httpURLConnection = getHttpURLConnection(url);
List<NameValuePair> postParams = new ArrayList<>();
//要传递的参数
postParams.add(new BasicNameValuePair("username", "moon"));
postParams.add(new BasicNameValuePair("password", "123"));
try {
postParams(httpURLConnection.getOutputStream(), postParams);
httpURLConnection.connect();  //通过调用connect方法建立TCP连接,但是并未真正获取数据。该方法也不必显式调用,当调用getInputStream方法时内部也会自动调用connect方法的
inputStream = httpURLConnection.getInputStream();  //调用getInputStream方法后,服务端才会收到请求,并阻塞式地接收服务端返回的数据
int code = httpURLConnection.getResponseCode();
String response = converStreamToString(inputStream);
Log.i("Debug", "请求状态码:" + code + "\n请求结果\n" + response);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}


HttpClient使用

private String converStreamToString(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = null;
while((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
String response = sb.toString();
return response;
}

private HttpClient createHttpClient() {
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 15000);  //设置连接超时时间
HttpConnectionParams.setSoTimeout(httpParams, 15000);  //设置请求超时时间
HttpConnectionParams.setTcpNoDelay(httpParams, true);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(httpParams, true);  //持续握手
HttpClient httpClient = new DefaultHttpClient(httpParams);
return httpClient;
}


GET方式:

public void useHttpClientGet(String url)
{
HttpGet httpGet = new HttpGet(url);
httpGet.addHeader("Connection", "Keep-Alive");
HttpClient httpClient = createHttpClient();
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
int code = httpResponse.getStatusLine().getStatusCode();
if (null != httpEntity)
{
InputStream inputStream = httpEntity.getContent();
String response = converStreamToString(inputStream);
Log.i("Debug", "请求状态码:" + code + "\n请求结果:\n" + response);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

POST方式:

private void useHttpClientPost(String url) {
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Connection", "Keep-Alive");
HttpClient httpClient = createHttpClient();
List<NameValuePair> postParams = new ArrayList<>();
//要传递的参数
postParams.add(new BasicNameValuePair("username", "moon"));
postParams.add(new BasicNameValuePair("password", "123"));
try {
httpPost.setEntity(new UrlEncodedFormEntity(postParams));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
int code = httpResponse.getStatusLine().getStatusCode();
if (null != httpEntity)
{
InputStream inputStream = httpEntity.getContent();
String response = converStreamToString(inputStream);
Log.i("Debug", "请求状态码:" + code + "\n请求结果:\n" + response);
inputStream.close();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: