`
oppal
  • 浏览: 10095 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Android开发实现HttpClient工具类以及HttpClient的3种超时说明【转】

 
阅读更多
使用单例模式实现自己的HttpClient工具类
引子

在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务。你可以把HttpClient想象成一个浏览器,通过它的API我们可以很方便的发出GET,POST请求(当然它的功能远不止这些)。

比如你只需以下几行代码就能发出一个简单的GET请求并打印响应结果:
复制代码

try {
        // 创建一个默认的HttpClient
        HttpClient httpclient =new DefaultHttpClient();
        // 创建一个GET请求
        HttpGet request =new HttpGet("www.google.com");
        // 发送GET请求,并将响应内容转换成字符串
        String response = httpclient.execute(request, new BasicResponseHandler());
        Log.v("response text", response);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

复制代码
为什么要使用单例HttpClient?

这只是一段演示代码,实际的项目中的请求与响应处理会复杂一些,并且还要考虑到代码的容错性,但是这并不是本篇的重点。注意代码的第三行:

HttpClient httpclient =new DefaultHttpClient();

在发出HTTP请求前,我们先创建了一个HttpClient对象。那么,在实际项目中,我们很可能在多处需要进行HTTP通信,这时候我们不需要为每个请求都创建一个新的HttpClient。因为之前已经提到,HttpClient就像一个小型的浏览器,对于整个应用,我们只需要一个HttpClient就够了。看到这里,一定有人心里想,这有什么难的,用单例啊!!就像这样:
复制代码

publicclass CustomerHttpClient {
    privatestatic HttpClient customerHttpClient;
    
    private CustomerHttpClient() {
    }
    
    publicstatic HttpClient getHttpClient() {
        if(null== customerHttpClient) {
            customerHttpClient =new DefaultHttpClient();
        }
        return customerHttpClient;
    }
}


复制代码

那么,哪里不对劲呢?或者说做的还不够完善呢?

多线程!试想,现在我们的应用程序使用同一个HttpClient来管理所有的Http请求,一旦出现并发请求,那么一定会出现多线程的问题。这就好像我们的浏览器只有一个标签页却有多个用户,A要上google,B要上baidu,这时浏览器就会忙不过来了。幸运的是,HttpClient提供了创建线程安全对象的API,帮助我们能很快地得到线程安全的“浏览器”。
解决多线程问题
复制代码

publicclass CustomerHttpClient {
    privatestaticfinal String CHARSET = HTTP.UTF_8;
    privatestatic HttpClient customerHttpClient;

    private CustomerHttpClient() {
    }

    publicstaticsynchronized HttpClient getHttpClient() {
        if (null== customerHttpClient) {
            HttpParams params =new BasicHttpParams();
            // 设置一些基本参数
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params,
                    CHARSET);
            HttpProtocolParams.setUseExpectContinue(params, true);
            HttpProtocolParams
                    .setUserAgent(
                            params,
                            "Mozilla/5.0(Linux;U;Android 2.2.1;en-us;Nexus One Build.FRG83) "
                                    +"AppleWebKit/553.1(KHTML,like Gecko) Version/4.0 Mobile Safari/533.1");
            // 超时设置
/* 从连接池中取连接的超时时间 */
            ConnManagerParams.setTimeout(params, 1000);
            /* 连接超时 */
            HttpConnectionParams.setConnectionTimeout(params, 2000);
            /* 请求超时 */
            HttpConnectionParams.setSoTimeout(params, 4000);
            
            // 设置我们的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(
                    params, schReg);
            customerHttpClient =new DefaultHttpClient(conMgr, params);
        }
        return customerHttpClient;
    }
}

复制代码

在上面的getHttpClient()方法中,我们为HttpClient配置了一些基本参数和超时设置,然后使用ThreadSafeClientConnManager来创建线程安全的HttpClient。上面的代码提到了3种超时设置,比较容易搞混,故在此特作辨析。
HttpClient的3种超时说明

/* 从连接池中取连接的超时时间 */
ConnManagerParams.setTimeout(params, 1000);

/* 连接超时 */
HttpConnectionParams.setConnectionTimeout(params, 2000);

/* 请求超时 */
HttpConnectionParams.setSoTimeout(params, 4000);




第一行设置ConnectionPoolTimeout:这定义了从ConnectionManager管理的连接池中取出连接的超时时间,此处设置为1秒。

第二行设置ConnectionTimeout:  这定义了通过网络与服务器建立连接的超时时间。Httpclient包中通过一个异步线程去创建与服务器的socket连接,这就是该socket连接的超时时间,此处设置为2秒。

第三行设置SocketTimeout:    这定义了Socket读数据的超时时间,即从服务器获取响应数据需要等待的时间,此处设置为4秒。

  

以上3种超时分别会抛出ConnectionPoolTimeoutException,ConnectionTimeoutException与SocketTimeoutException。 
封装简单的POST请求

有了单例的HttpClient对象,我们就可以把一些常用的发出GET和POST请求的代码也封装起来,写进我们的工具类中了。目前我仅仅实现发出POST请求并返回响应字符串的方法以供大家参考。将以下代码加入我们的CustomerHttpClient类中:
复制代码

privatestaticfinal String TAG ="CustomerHttpClient";

publicstatic String post(String url, NameValuePair... params) {
        try {
            // 编码参数
            List<NameValuePair> formparams =new ArrayList<NameValuePair>(); // 请求参数
for (NameValuePair p : params) {
                formparams.add(p);
            }
            UrlEncodedFormEntity entity =new UrlEncodedFormEntity(formparams,
                    CHARSET);
            // 创建POST请求
            HttpPost request =new HttpPost(url);
            request.setEntity(entity);
            // 发送请求
            HttpClient client = getHttpClient();
            HttpResponse response = client.execute(request);
            if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                thrownew RuntimeException("请求失败");
            }
            HttpEntity resEntity =  response.getEntity();
            return (resEntity ==null) ?null : EntityUtils.toString(resEntity, CHARSET);
        } catch (UnsupportedEncodingException e) {
            Log.w(TAG, e.getMessage());
            returnnull;
        } catch (ClientProtocolException e) {
            Log.w(TAG, e.getMessage());
            returnnull;
        } catch (IOException e) {
            thrownew RuntimeException("连接失败", e);
        }

    } 


复制代码
使用我们的CustomerHttpClient工具类

现在,在整个项目中我们都能很方便的使用该工具类来进行网络通信的业务代码编写了。下面的代码演示了如何使用username和password注册一个账户并得到新账户ID。
复制代码

final String url ="http://yourdomain/context/adduser";
    //准备数据
    NameValuePair param1 =new BasicNameValuePair("username", "张三");
    NameValuePair param2 =new BasicNameValuePair("password", "123456");
    int resultId =-1;
    try {
        // 使用工具类直接发出POST请求,服务器返回json数据,比如"{userid:12}"
        String response = CustomerHttpClient.post(url, param1, param2);
        JSONObject root =new JSONObject(response);
        resultId = Integer.parseInt(root.getString("userid"));
        Log.i(TAG, "新用户ID:"+ resultId);
    } catch (RuntimeException e) {
        // 请求失败或者连接失败
        Log.w(TAG, e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
    } catch (Exception e) {
        // JSon解析出错
        Log.w(TAG, e.getMessage());
    }

复制代码
结语

可以看到,使用工具类能大大提高在项目中编写网络通信代码的效率。不过该工具类还有待完善,欢迎各位补充和矫正错误,希望最后能完成一个工具类作为使用HttpClient的最佳实践。(完)

欢迎转载,但是转载请注明出处http://www.cnblogs.com/codingmyworld/archive/2011/08/17/2141706.html 
分享到:
评论

相关推荐

    Android HttpClient工具类

    7. **EntityUtils**:一个工具类,用于处理响应实体,如读取响应内容。例如: ```java String responseBody = EntityUtils.toString(response.getEntity()); ``` 8. **HttpContext**:提供了请求执行的上下文...

    HttpClientHelper 工具类

    HttpClientHelper 是一个C#编写的工具类,主要目的是简化HTTP客户端操作,提供同步和异步的请求方法,返回数据格式多样,包括字符串、泛型类型和XML。在爬虫开发中,这样的工具类非常实用,因为爬虫经常需要与各种...

    HttpClient工具类

    HttpClient工具类是Java开发中常用的一个HTTP客户端库,主要用于发送HTTP请求并接收响应。这个工具类通常是开发者为了方便地调用HttpClient库而封装的一系列静态方法。HttpClient支持各种HTTP方法,如GET、POST、PUT...

    httpclient4.3工具类

    在Java开发中,Apache HttpClient库是一个非常重要的工具,它提供了丰富的功能来处理HTTP请求和响应。HttpClient 4.3版本是其...理解这个工具类的内部实现和HttpClient的核心概念,将有助于更好地利用它进行HTTP通信。

    Android-HttpClient工具类简单轻松的实现getpostput和delete请求

    本篇文章将详细讲解如何使用`HttpClient`工具类来简化这些网络请求的实现。 首先,我们需要引入`HttpClient`的相关依赖。在Android Studio中,如果使用的是旧版本的Android SDK(低于API 22),系统自带了`...

    HttpClient接口调用工具类(附带demo)

    总之,这个HttpClient工具类提供了一个简洁易用的接口,帮助开发者快速、方便地进行HTTP请求,无论是在进行API调用还是数据交互,都能大大简化工作流程。通过这个工具类,你无需深入了解HttpClient的底层实现,只需...

    httpclient 工具类

    在本文中,我们将深入探讨HttpClient工具类的创建与使用,以及如何自定义返回的对象。 首先,我们需要引入HttpClient的相关依赖。在Maven项目中,可以在pom.xml文件中添加以下依赖: ```xml &lt;groupId&gt;org.apache...

    Android的HttpClient开发实例

    本开发实例将带你深入理解如何在Android项目中使用`HttpClient`进行网络请求,实现数据的获取和上传。 首先,`HttpClient`是Apache的一个开源项目,它提供了一个强大的API来处理HTTP协议。`commons-httpclient-3.1....

    httpclient4.3 封装工具类

    这个封裝工具类是对HttpClient 4.3进行的二次开发,旨在简化HTTP请求的处理,解决一些常见的问题,如代理设置、多线程并发请求、SSL安全连接以及GET和POST请求的通用实现。 1. **代理问题**:在进行网络请求时,...

    HttpClientUtil工具类发送get和post请求,支持http和https,支持发送文件

    下面我们将详细讨论HttpClientUtil工具类如何实现这些功能。 首先,HttpClientUtil工具类通常会封装HttpClient的基本操作,以便于开发者在应用中便捷地调用。GET和POST请求是HTTP协议中最常见的两种请求方法。GET...

    httpClient工具类

    在实际项目中,通常会封装一个HttpClient工具类,将上述操作抽象成便捷的方法,方便其他代码调用。文件`httpClientUtil`可能就是这样一个工具类,包含了上述功能的实现。通过阅读和理解这个工具类的代码,我们可以更...

    httpclient工具类包

    本文将深入探讨HttpClient工具类包,包括其核心组件、功能特性以及如何使用。 HttpClient库主要由两个核心组件构成:HttpCore和HttpClient。HttpCore是HttpClient的基础,提供了网络I/O操作的基本实现,如TCP连接...

    HttpClient工具类封装.docx

    【HttpClient工具类封装】 在Java开发中,Apache HttpClient是一个强大的HTTP客户端库,常用于执行HTTP请求,如GET、POST、PUT和DELETE等。这个工具类是基于HttpClient 4.5.12版本进行封装,目的是简化HTTP操作并...

    HTTPClient工具类及架包

    通过以上步骤,开发者可以使用HTTPClient工具类高效地执行HTTP请求,获取并处理服务器的响应。这个工具类集合的目的是简化这一过程,使得代码更加简洁易懂,同时也提高了开发效率。在实际应用中,可以根据具体需求...

    httpclient4.3 封装工具类.zip

    以下是一些关于HttpClient 4.3以及如何封装工具类的关键知识点: 1. **HttpClient 4.3核心概念**: - **HttpClient实例**:HttpClient是HTTP请求的载体,通过`HttpClientBuilder`或`HttpClients`静态方法创建。 -...

    对于C#(HttpClient)方式网络请求的封装

    - **Util.cs**:通用工具类,可能包含一些辅助函数,如日志记录、数据转换等,这些可能在处理网络请求时用到。 通过学习这些文件和博客文章,开发者可以更好地理解如何在Unity环境中高效且灵活地处理网络通信,从而...

    Android HttpClient源码

    在这个"Android HttpClient源码"中,我们可以深入理解其内部工作原理,并学习如何在Android应用中有效地使用它。 首先,HttpClient的核心类是`HttpClient`,它是整个HTTP客户端操作的管理者。通过`HttpClient`,...

    Android_HttpClient_jar包+HttpClientJarAndSource

    在Android系统中,HttpClient提供了一套完整的API,使得开发者能够方便地进行HTTP请求,发送POST、GET等方法,处理响应数据,以及实现Cookie管理、重定向等功能。 二、HttpClient在Android中的应用 1. 发起HTTP...

Global site tag (gtag.js) - Google Analytics