转自:点击打开链接

相信很多Android开发者碰到涉及到Http协议的需求时,都和我一样在犹豫是使用HttpClient还是使用HttpURLConnection呢。我在网上也搜索了很多文章,来分析两者的区别。接下来我们就剖析一下这两个网络开源库,分别从背景、用法、相同点、区别这几点来入手分析。

目录


补充知识


  • TCP/IP、Socket、HTTP简要介绍

    1. TCP/IP中文名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。

    2. Socket是支持TCP/IP协议的网络通信基本操作单元,许多操作系统为应用程序提供了一套调用接口(API),方便开发者开发网络程序。注意,socket本身并不是协议,只是提供一个针对TCP或UDP的编程接口。

    3. HTTP协议是一个web服务器和客户端通信的超文本传送协议,是建立在TCP协议上的一个应用层协议。

      HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

  • HTTP1.0

    客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

  • HTTP1.1

    可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

背景


  • HttpClient

    Apache公司提供的库,提供高效的、最新的、功能丰富的支持HTTP协议工具包,支持HTTP协议最新的版本和建议,是个很不错的开源框架,封装了http的请求,参数,内容体,响应等,拥有众多API。

  • HttpURLConnection

    Sun公司提供的库,也是Java的标准类库java.net中的一员,但这个类什么都没封装,用起来很原始,若需要高级功能,则会显得不太方便,比如重访问的自定义,会话和cookie等一些高级功能。

用法


这两种方式都支持HTTPS协议,以流的形式进行上传和下载,配置超时时间,IPV6,连接池等功能。

HttpClient的用法

一、执行请求

HttpClient最重要的功能是执行HTTP方法。一个HTTP方法的执行包含一个或多个HTTP请求/HTTP响应交流,通常由HttpClient的内部来处理。用户提供一个请求对象,HttpClient发送请求到目标服务器,希望服务器返回一个相应的响应对象,或者抛出一个异常(执行失败)。

一个简单的请求执行过程的示例:

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
int l;
byte[] tmp = new byte[2048];
while ((l = instream.read(tmp)) != -1) {
}
}

二、用工具封装Get请求

对比下面两段代码,发现用httpClient提供的方法更具可读性

HttpGet httpget = new HttpGet(
"http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");

HttpClient提供很多工具方法来简化创建和修改执行URI,例如:

List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("q", "httpclient"));
qparams.add(new BasicNameValuePair("btnG", "Google Search"));
qparams.add(new BasicNameValuePair("aq", "f"));
qparams.add(new BasicNameValuePair("oq", null));
URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
URLEncodedUtils.format(qparams, "UTF-8"), null);
HttpGet httpget = new HttpGet(uri);

三、处理头部消息

一个HTTP消息可以包含一系列头部描述消息的属性。例如:内容长度、内容类型等。

HttpClient提供方法检索、添加、删除、枚举头部信息。

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie","c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie","c2=b; path=/; domain=localhost");
//获取header的方法1
Header h1 = response.getFirstHeader("Set-Cookie");
Header h2 = response.getLastHeader("Set-Cookie");
//获取header的方法2
HeaderIterator it = response.headerIterator("Set-Cookie");
while (it.hasNext()) {
System.out.println(it.next());
}
//获取header的方法3
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
System.out.println(header.getName() + " | " + header.getValue());
}

四、HTTP实体

HTTP规范定义了两种包装实体的方法:POST和PUT。响应通常附上内容实体。

HttpClient根据其内容出自何处区分三种类型的实体:

  1. streamed(流式):内容从流中获得,或者在运行中产生。流式实体是不可重复生成的。

  2. self-contained(自我包装式):内容在内存中或通过独立的连接或其它实体中获得。自我包装式的实体是可以重复生成和读取的。经常用于封装HTTP请求实体。(像ByteArrayEntity或StringEntity)。

  3. wrapping(包裹式):内容从另外一个实体中获得。

如果从一个HTTP响应中获取流式内容,这个区别对于连接管理很重要。

如果是应用程序创建并用于发送的请求实体,这个类型区别就没那么重要了。

五、使用HTTP实体

使用实体常用的一些API,得到内容类型、内容长度、内容编码、内容转换成String或ByteArray、设置分块(HTTP1.1)。但是,EntityUtils的使用是不鼓励的,除非实体响应来自一个可信赖的HTTP服务器和已知的有限长度。

myEntity.getContentType()
myEntity.getContentLength()
EntityUtils.getContentCharSet(myEntity)
EntityUtils.toString(myEntity)
EntityUtils.toByteArray(myEntity)
myEntity.setChunked(true);

六、得到实体内容

HttpGet httpget = new HttpGet("http://localhost/");
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {
System.out.println(EntityUtils.toString(entity));
} else {
InputStream instream = entity.getContent();
int byteOne = instream.read();
int byteTwo = instream.read();
//终止请求,该连接将不被重用,保证底层的资源被正确释放
httpget.abort();
}
}

七、生成实体内容

HttpClient提供了常见的数据容器,比如字符串,字节数组,输入流和文件:StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity。

File file = new File("somefile.txt");
FileEntity entity = new FileEntity(file, "text/plain; charset=\"UTF-8\"");
HttpPost httppost = new HttpPost("http://localhost/action.do");
httppost.setEntity(entity);

八、HTML表单(UrlEncodedFormEntity)

许多应用程序需要频繁模拟提交一个HTML表单的过程,比如,为了来记录一个Web应用程序或提交输出数据。HttpClient提供了特殊的实体类UrlEncodedFormEntity来这个满足过程。

List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
//生成的实体内容:param1=value1¶m2=value2
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);

九、响应处理器(ResponseHandler)

ResponseHandler能够保证在任何情况下都会将底层的HTTP连接释放回连接管理器。用户不必担心HttpClient连接占用系统资源,可以把注意力集中在处理HTTP响应内容。

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://localhost/");
ResponseHandler<byte[]> handler = new ResponseHandler<byte[]>() {
public byte[] handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
if (entity != null) {
return EntityUtils.toByteArray(entity);
} else {
return null;
}
}
};
byte[] response = httpclient.execute(httpget, handler);

HttpClient还提供了很多高级的特性,如:连接管理、状态管理、认证管理、客户服务等。这里只介绍了一些基础的用法,有时间好好研究一下,再专门写一篇关于HttpClient的博客。

HttpClient和HttpURLConnection的使用和区别(上)的更多相关文章

  1. HttpClient和HttpURLConnection的使用和区别(下)

    转自来自点击打开链接 接着上一篇,我们继续来分析HttpURLConnection的使用,以及两者的共同点和区别. 目录 用法 HttpURLConnection 区别 引用资料 用法 HttpURL ...

  2. HttpClient和HttpURLConnection的使用和区别

    https://www.cnblogs.com/liushuibufu/p/4140913.html 功能用法对比 从功能上对比,HttpURLConnection比HttpClient库要丰富很多, ...

  3. java分别通过httpclient和HttpURLConnection获取图片验证码内容

    前面的文章,介绍了如何通过selenium+Tesseract-OCR来识别图片验证码,如果用接口来访问的话,再用selenium就闲的笨重,下面就介绍一下分别通过httpclient和HttpURL ...

  4. Android 网络编程之---HttpClient 与 HttpURLConnection 共用cookie

    HttpClient 与 HttpURLConnection 共用 SessionId HttpClient 与 HttpUrlConnection 是Android 中HTTP操作最常见的訪问方式. ...

  5. 为HttpClient和HttpURLConnection添加中国移动代理

    转自: http://www.2cto.com/kf/201111/112100.html 在android中,一般需要联网的时候前,都要做一次网络的判断,判断当前的网络状态!然后开始请求网络 当我们 ...

  6. HttpClient和HttpURLConnection的区别

    总结了网上的一些资源,主要有以下两个观点: 分析一: 在研究Volley框架的源码中,发现它在HTTP请求的使用上比较有意思,在Android 2.3及以上版本,使用的是HttpURLConnecti ...

  7. [Android]HttpClient和HttpURLConnection的区别

    转载:http://blog.csdn.net/guolin_blog/article/details/12452307 最近在研究Volley框架的源码,发现它在HTTP请求的使用上比较有意思,在A ...

  8. HTTP基础与Android之(安卓与服务器通信)——使用HttpClient和HttpURLConnection

    查看原文:http://blog.csdn.net/sinat_29912455/article/details/51122286 1客户端连接服务器实现内部的原理 GET方式和POST方式的差别 H ...

  9. Android 实现http通信(servlet做服务器端) HttpClient、HttpURLConnection实现登录验证

    一,写好服务器端 在eclipse或其它javaee开发工具中新建一个web项目(我这里的项目名是:Android),建一个servlet(我这里的servlet名是:LoginServlet),模拟 ...

随机推荐

  1. part1:1-embeded学习心态

    遇到问题,要冷静分析问题,采用排除法,个个排除查找问题之所在!切记!在没分析完自己问题之前,别把问题所在指向他人!

  2. Android中webview跟JAVASCRIPT中的交互

    在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...

  3. 《Delphi XE6 android 编程入门教程》推荐

    近5.6年已经没有看见关于delphi的新技术的书出来了(看来在国内delphi的使用量确实很低了), 高勇同学最近出了一本<Delphi XE6 android 编程入门教程>,上周刚拿 ...

  4. 2018.09.27 bzoj2118: 墨墨的等式(最短路+背包)

    传送门 好题啊. 首先找到最小的一个非零系数记做a1a_1a1​,然后如果WWW modmodmod a1=W′a_1=W'a1​=W′ modmodmod a1a_1a1​,且WWW是方程的一个可行 ...

  5. 2018.09.16 bzoj1176: [Balkan2007]Mokia(cdq分治)

    传送门 调了半天发现是输出优化打错了求心理阴影体积233 这题很简单啊. 一个修改操作x如果对一个询问操作y有贡献那么有. tx<ty,Xx<=Xy,Yx<=Yy" rol ...

  6. 2018.09.15 秘密的牛奶管道SECRET(次小生成树)

    描述 约翰叔叔希望能够廉价连接他的供水系统,但是他不希望他的竞争对手知道他选择的路线.一般这样的问题需要选择最便宜的方式,所以他决定避免这种情况而采用第二便宜的方式. 现在有W(3 <= W & ...

  7. 2018.09.12 poj3621Sightseeing Cows(01分数规划+spfa判环)

    传送门 01分数规划板题啊. 发现就是一个最优比率环. 这个直接二分+spfa判负环就行了. 代码: #include<iostream> #include<cstdio> # ...

  8. web页面中a标签下载文件包含中文下载失败的解决

    之前用到的文件下载,文件名都是时间戳的形式或者英文名.下载没有问题.后来附件有中文后写在页面是下面效果,点击下载,下载失败. 对应链接拿出来.是如下效果 之前用了各种其他办法都不理想,比如转义什么的. ...

  9. UVaLive 6525 Attacking rooks (二分图最大匹配)

    题意:给定一个 n * n的图,X是卒, . 是空位置,让你放尽量多的车,使得他们不互相攻击. 析:把每行连续的 . 看成X集体的一个点,同理也是这样,然后求一个最大匹配即可. 代码如下: #prag ...

  10. UltraEdit配置

    1.如何在vivado中调用UltraEdit 1.语法高亮 支持不同的编程语言,但是要添加相就的文件,这样不同语言的关键字就可以高亮显示. 在高级-> 配置 –> 语法高亮,选择文档 2 ...