Android网络编程之HttpUrlConnection、HttpClient

这篇文章我们共同来学习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方式:

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();
    }
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值