`
chriszeng87
  • 浏览: 741111 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android HttpClient

阅读更多

        HttpClient是Apache开源组织提供的一个开源的项目,从名字上就可以看出,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接受HTTP响应。但是不会缓存服务器的响应,不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。

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

  

HttpClient

  HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。

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

  AndroidHttpClient对于DefaultHttpClient做了一些改进,使其更使用用于Android项目:

  1. 关掉过期检查,自连接可以打破所有的时间限制。
  2. 可以设置ConnectionTimeOut(连接超时)和SoTimeout(读取数据超时)。
  3. 关掉重定向。
  4. 使用一个Session缓冲用于SSL Sockets。
  5. 如果服务器支持,使用gzip压缩方式用于在服务端和客户端传递的数据。
  6. 默认情况下不保留Cookie。    

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

  1. 创建HttpClient对象。
  2. 创建对应的发送请求的对象,如果需要发送GET请求,则创建HttpGet对象,如果需要发送POST请求,则创建HttpPost对象。
  3. 对于发送请求的参数,GET和POST使用的方式不同,GET方式可以使用拼接字符串的方式,把参数拼接在URL结尾;POST方式需要使用setEntity(HttpEntity entity)方法来设置请求参数。
  4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse对象。
  5. 调用HttpResponse的对应方法获取服务器的响应头、响应内容等。

DefaultHttpClient

  先看看使用DefaultHttpClient方式发送Web站点请求,上面已经简要说明了步骤,在这里简要说明一个参数的传递问题,对于GET方式,只需要拼接字符串就在URL结尾即可,但是对于POST方式,需要传递HttpEntity对象,HttpEntity为一个接口,有多个实现类,可以使用其间接子继承,UrlEncodedFormEntity类来保存请求参数,并传递给HttpPost。

  此例子简单实现了在Android客户端使用DefaultHttpClient实现一个Http站点登陆的实现,使用的是POST传递,其传递值只需要传递username+password即可,当传递的数据为admin+123则认为登陆成功。Web站点使用.net的架构,一个一般处理程序,简单的比对账户密码,这里就不在此讲解。

  因为Android4.0之后对使用网络有特殊要求,已经无法再在主线程中访问网络了,必须使用多线程访问的模式,其他的一些信息在代码注释中已经说明。

 DefaultHttpClient-Code

复制代码
  1 package com.bgxt.httpUtils;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.UnsupportedEncodingException;
  7 import java.util.ArrayList;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.Map;
 11 
 12 import org.apache.http.HttpResponse;
 13 import org.apache.http.NameValuePair;
 14 import org.apache.http.client.ClientProtocolException;
 15 import org.apache.http.client.entity.UrlEncodedFormEntity;
 16 import org.apache.http.client.methods.HttpPost;
 17 import org.apache.http.impl.client.DefaultHttpClient;
 18 import org.apache.http.message.BasicNameValuePair;
 19 
 20 public class httpClientUtils implements Runnable {
 21     /**
 22      * 对于Android4.0之上的环境下,不能在主线程中访问网络 所以这里另新建了一个实现了Runnable接口的Http访问类
 23      */
 24     private String username;
 25     private String password;
 26 
 27     public httpClientUtils(String username, String password) {
 28         // 初始化用户名和密码
 29         this.username = username;
 30         this.password = password;
 31     }
 32 
 33     @Override
 34     public void run() {
 35         // 设置访问的Web站点
 36         String path = "http://192.168.1.103:1231/loginas.ashx";
 37         // 设置Http请求参数
 38         Map<String, String> params = new HashMap<String, String>();
 39         params.put("username", username);
 40         params.put("password", password);
 41 
 42         String result = sendHttpClientPost(path, params, "utf-8");
 43         // 把返回的接口输出
 44         System.out.println(result);
 45     }
 46 
 47     /**
 48      * 发送Http请求到Web站点
 49      * 
 50      * @param path
 51      *            Web站点请求地址
 52      * @param map
 53      *            Http请求参数
 54      * @param encode
 55      *            编码格式
 56      * @return Web站点响应的字符串
 57      */
 58     private String sendHttpClientPost(String path, Map<String, String> map,
 59             String encode) {
 60         List<NameValuePair> list = new ArrayList<NameValuePair>();
 61         if (map != null && !map.isEmpty()) {
 62             for (Map.Entry<String, String> entry : map.entrySet()) {
 63                 // 解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。
 64                 list.add(new BasicNameValuePair(entry.getKey(), entry
 65                         .getValue()));
 66             }
 67         }
 68         try {
 69             // 实现将请求 的参数封装封装到HttpEntity中。
 70             UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode);
 71             // 使用HttpPost请求方式
 72             HttpPost httpPost = new HttpPost(path);
 73             // 设置请求参数到Form中。
 74             httpPost.setEntity(entity);
 75             // 实例化一个默认的Http客户端
 76             DefaultHttpClient client = new DefaultHttpClient();
 77             // 执行请求,并获得响应数据
 78             HttpResponse httpResponse = client.execute(httpPost);
 79             // 判断是否请求成功,为200时表示成功,其他均问有问题。
 80             if (httpResponse.getStatusLine().getStatusCode() == 200) {
 81                 // 通过HttpEntity获得响应流
 82                 InputStream inputStream = httpResponse.getEntity().getContent();
 83                 return changeInputStream(inputStream, encode);
 84             }
 85         } catch (UnsupportedEncodingException e) {
 86             e.printStackTrace();
 87         } catch (ClientProtocolException e) {
 88             e.printStackTrace();
 89         } catch (IOException e) {
 90             e.printStackTrace();
 91         }
 92         return "";
 93     }
 94 
 95     /**
 96      * 把Web站点返回的响应流转换为字符串格式
 97      * 
 98      * @param inputStream
 99      *            响应流
100      * @param encode
101      *            编码格式
102      * @return 转换后的字符串
103      */
104     private String changeInputStream(InputStream inputStream, String encode) {
105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
106         byte[] data = new byte[1024];
107         int len = 0;
108         String result = "";
109         if (inputStream != null) {
110             try {
111                 while ((len = inputStream.read(data)) != -1) {
112                     outputStream.write(data, 0, len);
113                 }
114                 result = new String(outputStream.toByteArray(), encode);
115 
116             } catch (IOException e) {
117                 e.printStackTrace();
118             }
119         }
120         return result;
121     }
122 
123 }
复制代码

AndroidHttpClient

  使用AndroidHttpClient的方式和DefaultHttpClient差不多,不多的几点区别上面已经说明,但是在此例子中没有体现。有一点需要注意的是,AndroidHttpClient是一个final类,也没有公开的构造函数,所以无法使用new的形式对其进行实例化,必须使用AndroidHttpClient.newInstance()方法获得AndroidHttpClient对象。

  示例中依然是使用POST请求,实现的功能和DefaultHttpClient示例一样。细节部分已经在注释中体现,直接看代码即可。

复制代码
  1 package com.bgxt.httpUtils;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.IOException;
  5 import java.io.InputStream;
  6 import java.io.UnsupportedEncodingException;
  7 import java.util.ArrayList;
  8 import java.util.HashMap;
  9 import java.util.List;
 10 import java.util.Map;
 11 
 12 import org.apache.http.HttpResponse;
 13 import org.apache.http.NameValuePair;
 14 import org.apache.http.client.ClientProtocolException;
 15 import org.apache.http.client.HttpClient;
 16 import org.apache.http.client.entity.UrlEncodedFormEntity;
 17 import org.apache.http.client.methods.HttpPost;
 18 import org.apache.http.impl.client.DefaultHttpClient;
 19 import org.apache.http.message.BasicNameValuePair;
 20 
 21 import android.net.http.AndroidHttpClient;
 22 
 23 public class AndroidHttpClientUtils implements Runnable {
 24 
 25     private String username;
 26     private String password;
 27 
 28     public AndroidHttpClientUtils(String username, String password) {
 29         // 初始化用户名和密码
 30         this.username = username;
 31         this.password = password;
 32     }
 33 
 34     @Override
 35     public void run() {
 36         // 设置访问的Web站点
 37         String path = "http://192.168.1.103:1231/loginas.ashx";
 38         //设置Http请求参数
 39         Map<String, String> params = new HashMap<String, String>();
 40         params.put("username", username);
 41         params.put("password", password);
 42 
 43         String result = sendHttpClientPost(path, params, "utf-8");
 44         //把返回的接口输出
 45         System.out.println(result);
 46     }
 47     /**
 48      * 发送Http请求到Web站点
 49      * @param path Web站点请求地址
 50      * @param map Http请求参数
 51      * @param encode 编码格式
 52      * @return Web站点响应的字符串
 53      */
 54     private String sendHttpClientPost(String path,Map<String, String> map,String encode)
 55     {
 56         List<NameValuePair> list=new ArrayList<NameValuePair>();
 57         if(map!=null&&!map.isEmpty())
 58         {
 59             for(Map.Entry<String, String> entry:map.entrySet())
 60             {
 61                 //解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。
 62                 list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
 63             }
 64         }
 65         try {
 66             //实现将请求 的参数封装封装到HttpEntity中。
 67             UrlEncodedFormEntity entity=new UrlEncodedFormEntity(list, encode);
 68             //使用HttpPost请求方式
 69             HttpPost httpPost=new HttpPost(path);
 70             //设置请求参数到Form中。
 71             httpPost.setEntity(entity);
 72             //实例化一个默认的Http客户端,使用的是AndroidHttpClient
 73             HttpClient client=AndroidHttpClient.newInstance("");
 74             //执行请求,并获得响应数据
 75             HttpResponse httpResponse= client.execute(httpPost);
 76             //判断是否请求成功,为200时表示成功,其他均问有问题。
 77             if(httpResponse.getStatusLine().getStatusCode()==200)
 78             {
 79                 //通过HttpEntity获得响应流
 80                 InputStream inputStream=httpResponse.getEntity().getContent();
 81                 return changeInputStream(inputStream,encode);
 82             }
 83             
 84         } catch (UnsupportedEncodingException e) {
 85             // TODO Auto-generated catch block
 86             e.printStackTrace();
 87         } catch (ClientProtocolException e) {
 88             // TODO Auto-generated catch block
 89             e.printStackTrace();
 90         } catch (IOException e) {
 91             // TODO Auto-generated catch block
 92             e.printStackTrace();
 93         }
 94         
 95         return "";
 96     }                    
 97     /**
 98      * 把Web站点返回的响应流转换为字符串格式
 99      * @param inputStream 响应流
100      * @param encode 编码格式
101      * @return 转换后的字符串
102      */
103     private  String changeInputStream(InputStream inputStream,
104             String encode) { 
105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
106         byte[] data = new byte[1024];
107         int len = 0;
108         String result="";
109         if (inputStream != null) {
110             try {
111                 while ((len = inputStream.read(data)) != -1) {
112                     outputStream.write(data,0,len);                    
113                 }
114                 result=new String(outputStream.toByteArray(),encode);
115                 
116             } catch (IOException e) {
117                 e.printStackTrace();
118             }
119         }
120         return result;
121     }
122 }
复制代码

  在本文的示例中,环境是使用的Android项目,可以对其进行简单的界面布局,如图:

  如果输入用户和密码为:admin+123,则可以再LogCat中查看到登录成功。

  示例代码下载地址:http://download.csdn.net/detail/plokmju88/5632307

 

总结

  最近的两次博客中,已经分别介绍了HttpUrlConnection和HttpClient两种方式,通过Http协议对Web站点的访问。如果还不了解HttpURLConnection的读者,可以看看“http://www.cnblogs.com/plokmju/p/java-HTTP.html”。

  根据官方文档上说的显示,Android包括两个Http客户端:HttpURLConnection和Apache HttpClient。并且都支持HTTPS,流媒体上传下载,并且可配置超时以及支持IPv6和连接池技术。但是因为移动设备的局限性,HttpURLConnection会是比Apache Http更好的选择,因为其API简单,运行消耗内存小,并且具有公开化的压缩算法,以及响应缓存,能更好的减少网络使用,提供运行速度和节省电池。

  但是也不能否认Apache HttpClient,它有大量的灵活的API,实现比较稳定,少有Bug,可造成的问题就是很难在不影响其兼容性的情况下对其进行改进了。现在Android开发者已经慢慢放弃Apache HttpClient的使用,转而使用HttpURLConnection。但是对于Android2.2之前的版本,HttpURLConnection具有一个致命的BUG,在响应输入流InputStream中调用.Close()方法将会阻碍连接池,因为这个BUG,只能放弃连接池的使用,但是Apache HttpClient不存在这个问题,当然Android2.3之后的版本中,HttpURLConnection已经解决了这个BUG,可以放心使用。

 

转自:http://www.cnblogs.com/plokmju/p/Android_apacheHttpClient.html

分享到:
评论

相关推荐

    Android HttpClient工具类

    本篇文章将深入探讨Android HttpClient的基本使用方法,帮助开发者理解和应用这个工具。 首先,我们来了解HttpClient的核心组件: 1. **HttpClient实例**:这是所有操作的基础,通过`HttpClient client = new ...

    Android HttpClient用到的jar包

    本篇将详细讲解如何利用Apache HttpClient及其相关的jar包在Android环境中进行文件上传。 首先,我们关注的是标题提到的两个jar包:“apache-mime4j-0.6.jar”和“httpmime-4.0.jar”。这两个jar包是HttpClient库的...

    android httpClient所需jar包

    本主题聚焦于"android httpClient所需jar包"以及与之相关的ksoap2库,这些都是Android应用开发中不可或缺的部分。 首先,让我们详细了解这些jar包的作用: 1. **commons-httpclient-3.1.jar**: 这是Apache ...

    android httpclient demo

    然而,由于Android API Level 23之后不再支持HttpClient,开发者现在更多地转向使用OkHttp或Retrofit等现代网络库。尽管如此,对于旧项目或者对HttpClient有特定需求的场景,理解其工作原理和用法仍然很有价值。 1....

    android httpClient

    然而,从Android API 23(Marshmallow)开始,HttpClient被标记为废弃,推荐使用Android的HttpURLConnection或者其他的第三方库如OkHttp、Retrofit等。尽管如此,对于理解Android网络编程的基础和历史,HttpClient...

    Android HttpClient源码

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

    android HttpClient

    在Android应用程序中,`HttpClient`经常被用于实现网络通信,比如上传或下载文件。下面将详细讨论`HttpClient`在Android中的应用及其相关知识点。 一、`HttpClient`基础 1. `HttpClient`类:它是整个框架的核心,...

    Android Httpclient Proxy Test

    本文将深入探讨如何在Android中使用HttpClient进行代理设置,并结合具体的例子来阐述相关知识点。 首先,了解`HttpClient`是Apache的一个开源库,它提供了一个强大的、功能丰富的HTTP客户端API,使得开发者可以方便...

    Android HttpClient与Json解析

    首先,我们需要了解如何使用Android的HttpClient。在Android SDK中,`org.apache.http.impl.client.DefaultHttpClient`是主要的HttpClient实现。创建一个HttpClient实例后,你可以通过`HttpGet`或`HttpPost`对象来...

    struts2 android httpclient 上传文件

    Struts2、Android和HttpClient是三个关键的技术领域,它们在本次文件上传的场景中相互结合。Struts2是一个流行的Java Web框架,用于构建MVC(模型-视图-控制器)结构的应用程序。Android是Google开发的移动操作系统...

    android httpclient

    android9.0不再支持useLibrary 'org.apache.http.legacy'引入httpclient,需要引入jar

    Android HttpClient Network Lib

    总结来说,`Android HttpClient Network Lib`是一个关于如何在Android应用中使用HttpClient进行网络通信的知识点,涵盖了HttpClient的基本使用方法、优势,以及如何利用提供的jar包和源码进行开发。虽然HttpClient已...

    android HttpClient 获取网络图片

    android HttpClient 获取网络图片 实例

    AndroidHttpClient详解及调用示例

    创建AndroidHttpClient对象非常简单,只需调用`AndroidHttpClient.newInstance(String userAgent)`,其中userAgent参数通常为空字符串。如果不需要设置代理,可以留空。例如: ```java AndroidHttpClient client = ...

    Android httpclient httpmine4j

    然而,Android原生的HttpClient并不支持Multipart/form-data类型的请求,这在上传文件时是个问题。为了解决这个问题,我们可以引入第三方库如`httpclient`和`httpmime`,特别是`httpmine4j`相关的组件。 `...

    android HttpClient访问Https

    android HttpClient访问某些Https时,出现了问题,无法访问,好像是要安全验证。此Demo解决了此问题,HttpClient能够Https和Http类型的URL了。 在eclipse下打开工程若有乱码,请把eclipse的字符编码改成UTF-8。

    AndroidHttpClient访问Tomcat双向SSL验证服务器.pdf

    ### AndroidHttpClient访问Tomcat双向SSL验证服务器 #### 环境与背景介绍 本文主要讨论如何使用`AndroidHttpClient`访问`Tomcat`双向SSL验证服务器的相关技术和实施步骤。本项目的目标是在`Android WebView`上成功...

    Android_HttpClient_jar包+HttpClientJarAndSource

    《Android HttpClient库详解与应用实践》 在移动开发领域,Android平台上的网络通信是一个至关重要的环节,HttpClient作为早期广泛使用的网络请求库,对于许多开发者来说并不陌生。本资源"Android_HttpClient_jar包...

    android httpclient4

    ### Android HttpClient4 使用详解 #### 一、概述 在Android应用开发中,网络通信是非常重要的一个环节。HttpClient作为Apache组织下的一个开源项目,为开发者提供了简单而强大的HTTP客户端功能。HttpClient 4.x...

    Android_HttpClient_jar包

    Android使用HttpClient发送请求、接收响应很简单,只要如下几步即可: Step1:创建HttpClient对象; Step2:如果需要发送GET请求,则创建HttpGet对象; 如果需要发送POST请求,则创建HttpPost对象; Step3:如果...

Global site tag (gtag.js) - Google Analytics