HttpClient使用详解

一、简介

HttpClientApache开源组织提供的HTTP网络访问接口,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接收HTTP响应,但是不会缓存服务器的响应,不能执行HTTP页面中嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。

现在Android已经成功集成了HttpClient,所以开发人员在Android项目中可以直接使用HttpClient来向Web站点提交请求以及接受响应,如果使用其他的Java项目则需要引入相应的Jar包。HttpClient可以在官网上下载,官网链接:http://hc.apache.org/downloads.cgi

HttpClient其实是一个interface类型,它封装了对象需要执行的HTTP请求、身份验证、连接管理和其它特性。由于HttpClient是一个接口,因此无法创建它的实例,但是HttpClient有三个已知的实现类分别是:AbstractHttpClientAndroidHttpClientDefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能。

从两个类包所在位置就可以看出区别:AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的HTTP访问;而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对Apache项目的支持。而AndroidHttpClient没有公开的构造函数,只能通过静态方法newInstance()方法来获得AndroidHttpClient对象。

二、特性

  1. 基于标准、纯净的Java语言,实现了Http1.0Http1.1
  2. 以可扩展的面向对象结构实现了HTTP全部的方法(GETPOSTPUTDELETEHEADOPTIONSTRACE);
  3. 支持HTTPS协议;
  4. 通过HTTP代理建立透明的连接;
  5. 利用CONNECT方法通过HTTP代理建立隧道的HTTPS连接;
  6. BasicDigestNTLMv1NTLMv2NTLM2 SessionSNPNEGO/Kerberos认证方案;
  7. 插件式的自定义认证方案;
  8. 便携可靠的套接字工厂使它更容易的使用第三方解决方案;
  9. 连接管理器支持多线程应用,支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接;
  10. 自动处理Set-Cookie中的Cookie
  11. 插件式的自定义Cookie策略;
  12. Request的输出流可以避免流中内容直接缓冲到Socket服务器;
  13. Response的输入流可以有效的从Socket服务器直接读取相应内容;
  14. Http1.0Http1.1中利用KeepAlive保持持久连接;
  15. 直接获取服务器发送的response codeheaders
  16. 设置连接超时的能力;
  17. 实验性的支持http1.1 response caching
  18. 源代码基于Apache License可免费获取;

三、集成

EclipseAndroid Studio开发过程中,设置Android SDK的编译版本为23且使用了HttpClient相关类的方法时会出现有一些类找不到的错误。

  1. 原因
    Android 6.0(API 23)SDK不再提供org.apache.http.*(只保留几个类)。

  2. 解决方法
    2.1 Eclipse:在项目libs中加入:org.apache.http.legacy.jar
    上面的jar包在:**\android-sdk-windows\platforms\android-23\optional下(需要下载Android 6.0SDK)。

    2.2 Android Studio:在项目相应modulebuild.gradle中加入:

    android {
        useLibrary 'org.apache.http.legacy'
    }

四、权限

AndroidManifest.xml文件添加网络权限

<uses-permission android:name="android.permission.INTERNET" />

五、混淆

#不混淆android-async-http(这里混淆由你使用的HttpClient框架决定)  
-keep class com.loopj.android.http.**{*;}  

#不混淆org.apache.http.legacy.jar   
-dontwarn android.net.compatibility.**  
-dontwarn android.net.http.**  
-dontwarn com.android.internal.http.multipart.**  
-dontwarn org.apache.commons.**  
-dontwarn org.apache.http.**  
-keep class android.net.compatibility.**{*;}  
-keep class android.net.http.**{*;}  
-keep class com.android.internal.http.multipart.**{*;}  
-keep class org.apache.commons.**{*;}  
-keep class org.apache.http.**{*;} 

六、使用

简单来说,使用HttpClient发送请求、接收响应都很简单,只需要五大步骤即可:

  1. 创建客户端的HttpClient对象;
  2. 创建请求的对象。如果需要发送GET请求,则创建HttpGet对象;如果需要发送POST请求,则创建HttpPost对象。注:对于发送请求的参数而言GETPOST的使用方式略有不同,GET方式可以使用拼接字符串的方式将参数拼接在URL末尾;POST方式则需要使用setEntityHttpEntity entity)方法来设置请求参数;
  3. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法后将获得服务器返回的HttpResponse对象。服务器返回给我们的数据就在这个HttpResponse相应当中,调用HttpResponse的对应方法可以获取服务器的响应头、响应内容等;
  4. 检查响应状态是否正常。服务器返回给客户端的响应有一个响应码:相应码为200时表示正常返回;相应码为404时表示客户端错误;相应码为505时表示服务器端错误;
  5. 获得响应对象当中的数据。

七、调用

主线程中访问网络时异常:NetworkOnMainThreadException

  1. 原因
    Android4.0之前的版本支持在主线程中访问网络,但是在4.0以后对这部分程序进行了优化,也就是说访问网络的代码不能写在主线程中了。
  2. 解决方法
    采用多线程、异步加载的方式加载数据。

八、示例

    public static final int CONNECTION_TIME_OUT = 1000 * 20;//连接超时
    public static final int SO_TIMEOUT = 1000 * 20;//Socket 超时
    public static final String ENCODING = "UTF-8";//编码格式

    /**
     * HttpClient Post 请求
     *
     * @param apiUrl    接口地址
     * @param paramsMap 接口参数
     * @return
     */
    public static ResultDesc postRequest(String apiUrl, Map<String, String> paramsMap) {
        // 创建表单
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if (paramsMap != null && paramsMap.size() != 0) {
            for (String key : paramsMap.keySet()) {
                params.add(new BasicNameValuePair(key, paramsMap.get(key)));
            }
        }

        //创建HttpClient对象
        HttpClient httpClient = getHttpClient();
        //创建请求对象,参数是访问的服务器地址
        HttpPost httpPost = new HttpPost(apiUrl);

        HttpResponse httpResponse;
        ResultDesc resultDesc = null;
        try {
            UrlEncodedFormEntity encode = new UrlEncodedFormEntity(params, ENCODING);
            httpPost.setEntity(encode);

            //执行请求,获取服务器返回的相应对象
            httpResponse = httpClient.execute(httpPost);
            //检查相应的状态是否正常,状态码返回值为200表示正常
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //从相应对象当中取出数据放到entity当中
                HttpEntity entity = httpResponse.getEntity();
                //将entity当中的数据转换为字符串
                String response = EntityUtils.toString(entity, ENCODING);

                LogUtil.e(Constant.LOG_TAG, "接口地址:" + apiUrl + "\n请求返回:" + response);

                resultDesc = getReturnData(response);
            } else {
                resultDesc = dataRestructuring(-1, UIUtils.getString(R.string.back_abnormal_results), "");
            }
        } catch (Exception e) {
            resultDesc = dataRestructuring(-1, ExceptionCode(e), "");
        }

        return resultDesc;
    }

    /**
     * HttpClient Get 请求
     *
     * @param apiUrl    接口地址
     * @param paramsMap 接口参数
     * @return
     */
    public static ResultDesc getRequest(String apiUrl, Map<String, String> paramsMap) {
        //创建表单
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if (paramsMap != null && paramsMap.size() != 0) {
            for (String key : paramsMap.keySet()) {
                params.add(new BasicNameValuePair(key, paramsMap.get(key)));
            }
            //对参数编码
            String param = URLEncodedUtils.format(params, ENCODING);
            apiUrl += "?" + param;
        }

        //创建HttpClient对象
        HttpClient httpClient = getHttpClient();
        //创建请求对象,参数是访问的服务器地址
        HttpGet httpGet = new HttpGet(apiUrl);

        HttpResponse httpResponse;
        ResultDesc resultDesc = null;
        try {
            //执行请求,获取服务器返回的相应对象
            httpResponse = httpClient.execute(httpGet);
            //检查相应的状态是否正常,状态码返回值为200表示正常
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                //从相应对象当中取出数据放到entity当中
                HttpEntity entity = httpResponse.getEntity();
                //将entity当中的数据转换为字符串
                String response = EntityUtils.toString(entity, ENCODING);

                LogUtil.e(Constant.LOG_TAG, "接口地址:" + apiUrl + "\n请求返回:" + response);

                resultDesc = getReturnData(response);
            } else {
                resultDesc = dataRestructuring(-1, UIUtils.getString(R.string.back_abnormal_results), "");
            }
        } catch (Exception e) {
            resultDesc = dataRestructuring(-1, ExceptionCode(e), "");
        }

        return resultDesc;
    }

    /**
     * HttpClient 配置
     *
     * @return
     */
    public static HttpClient getHttpClient() {
        //创建HttpParams以用来设置HTTP参数(这一部分不是必需的)
        BasicHttpParams httpParams = new BasicHttpParams();
        //设置连接超时
        HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIME_OUT);
        //设置Socket超时
        HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
        //设置Socket缓存大小
        HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
        //设置userAgent
        String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
        HttpProtocolParams.setUserAgent(httpParams, userAgent);

        //设置重定向,缺省为true
        //HttpClientParams.setRedirecting(httpParams, true);
        //设置HttpClient支持HTTP和HTTPS两种模式
        //SchemeRegistry schReg = new SchemeRegistry();
        //schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        //schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
        //使用线程安全的连接管理来创建HttpClient
        //ClientConnectionManager conMgr = new ThreadSafeClientConnManager(httpParams, schReg);
        //创建HttpClient对象
        //HttpClient httpClient = new DefaultHttpClient(conMgr, httpParams);

        //创建HttpClient对象
        HttpClient httpClient = new DefaultHttpClient(httpParams);
        return httpClient;
    }

项目地址 ☞ 传送门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值