HttpClient和HttpURLConnection的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClient和HttpURLConnection的区别相关的知识,希望对你有一定的参考价值。
ttpClient是个开源框架,封装了访问http的请求头,参数,内容体,响应等等,HttpURLConnection是java的标准类,什么都没封装,用起来太原始,不方便
HttpClient实际上是对Java提供方法的一些封装,
在HttpURLConnection中的输入输出流操作,
在这个接口中被统一封装成了HttpPost(HttpGet)和HttpResponse,
这样,就减少了操作的繁琐性。
性能方面这里做一个测试:
HttpURLConnection VS HttpClient性能测试
版本: HttpURLConnection jdk1.6;HttpClient 3.0.1
在项目中有一个特别小的相关应用,在选择时做了一下测试,之前先对两个类进行下说明:
HttpURLConnection java的标准类(java.net)
HttpClient Jakarta Commons HttpClient,提供对HTTP协议访问的封装,包括http的请求头,参数,内容体,响应等及多线程的应用。
测试代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class HttpClientTest
private static String link = "http://www.baidu.com";
public static void main(String[] args)
long a = System.currentTimeMillis();
useHttpURlConnection();
long b = System.currentTimeMillis();
System.out.println("use httpurlconnection: "+(b-a));
long c = System.currentTimeMillis();
useHttpClient();
long d = System.currentTimeMillis();
System.out.println("use httpclient: "+(d-c));
public static void useHttpURlConnection()
HttpURLConnection conn = null;
URL url = null;
String result = "";
try
url = new java.net.URL(link);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(10000);
conn.connect();
InputStream urlStream = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlStream));
String s = "";
while ((s = reader.readLine()) != null)
result += s;
System.out.println(result);
reader.close();
urlStream.close();
conn.disconnect();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch(Exception e)
e.printStackTrace();
public static void useHttpClient()
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(link);
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK)
System.err.println("Method failed: " + method.getStatusLine());
byte[] responseBody = method.getResponseBody();
System.out.println(new String(responseBody));
catch (HttpException e)
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
catch (IOException e)
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
finally
method.releaseConnection();
参考技术A 大多数的android应用程序都会使用HTTP协议来发送和接收网络数据,而Android中主要提供了两种方式来进行HTTP操作,HttpURLConnection和HttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、以及连接池等功能。
HttpClient:
DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具体的实现类,它们都拥有众多的API,而且实现比较稳定,bug数量也很少。
但同时也由于HttpClient的API数量过多,使得我们很难在不破坏兼容性的情况下对它进行升级和扩展,所以目前Android团队在提升和优化HttpClient方面的工作态度并不积极。
HttpURLConnection:
HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。虽然HttpURLConnection的API提供的比较简单,但是同时这也使得我们可以更加容易地去使用和扩展它。
不过在Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
[java] view plaincopy
private void disableConnectionReuseIfNecessary()
// 这是一个2.2版本之前的bug
if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO)
System.setProperty("http.keepAlive", "false");
配置你的Web服务器来支持对客户端的响应进行压缩的功能,从而可以在这一改进上获取到最大的好处。如果在压缩响应的时候出现了问题,这篇文档会告诉你如何禁用掉这个功能。
但是如果启动了响应压缩的功能,HTTP响应头里的Content-Length就会代表着压缩后的长度,这时再使用getContentLength()方法来取出解压后的数据就是错误的了。正确的做法应该是一直调用InputStream.read()方法来读取响应数据,一直到出现-1为止。
我们在Android 2.3版本中还增加了一些HTTPS方面的改进,现在HttpsURLConnection会使用SNI(Server Name Indication)的方式进行连接,使得多个HTTPS主机可以共享同一个IP地址。除此之外,还增加了一些压缩和会话的机制。如果连接失败,它会自动去尝试重新进行连接。这使得HttpsURLConnection可以在不破坏老版本兼容性的前提下,更加高效地连接最新的服务器。
在Android 4.0版本中,我们又添加了一些响应的缓存机制。当缓存被安装后(调用HttpResponseCache的install()方法),所有的HTTP请求都会满足以下三种情况:
所有的缓存响应都由本地存储来提供。因为没有必要去发起任务的网络连接请求,所有的响应都可以立刻获取到。
视情况而定的缓存响应必须要有服务器来进行更新检查。比如说客户端发起了一条类似于 “如果/foo.png这张图片发生了改变,就将它发送给我” 这样的请求,服务器需要将更新后的数据进行返回,或者返回一个304 Not Modified状态。如果请求的内容没有发生,客户端就不会下载任何数据。
没有缓存的响应都是由服务器直接提供的。这部分响应会在稍后存储到响应缓存中。
由于这个功能是在4.0之后的版本才有的,通常我们就可以使用反射的方式来启动响应缓存功能。下面的示例代码展示了如何在Android 4.0及以后的版本中去启用响应缓存的功能,同时还不会影响到之前的版本:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
[java] view plaincopy
private void enableHttpResponseCache()
try
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.htt p www.hbbz08.com .HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
catch (Exception httpResponseCacheNotAvailable)
你也应该同时配置一下你的Web服务器,在HTTP响应上加入缓存的消息头。哪一种才是最好的?在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。
而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。
分析二:
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:HttpURLConnection。
HttpURLConnection是java的标准类,HttpURLConnection继承自URLConnection,可用于向指定网站发送GET请求、POST请求。它在URLConnection的基础上提供了如下便捷的方法:
int getResponseCode():获取服务器的响应代码。
String getResponseMessage():获取服务器的响应消息。
String getResponseMethod():获取发送请求的方法。
void setRequestMethod(String method):设置发送请求的方法。
在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行html页面中嵌入的javascript代码;也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收
响应,以及管理HTTP连接。
使用HttpClient发送请求、接收响应很简单,只要如下几步即可。
创建HttpClient对象。
如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HetpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse。
调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
另外,Android已经成功地集成了HttpClient,这意味着开发人员可以直接在Android应用中使用Httpclient来访问提交请求、接收响应。
比如一个Android应用需要向指定页面发送请求,但该页面并不是一个简单的页面,只有当用户已经登录,而且登录用户的用户名有效时才可访问该页面。如果使用HttpURLConnection来访问这个被保护的页面,那么需要处理的细节就太复杂了。
其实访问Web应用中被保护的页面,使用浏览器则十分简单,用户通过系统提供的登录页面登录系统,浏览器会负责维护与服务器之间的Sesion,如果用户登录的用户名、密码符合要求,就可以访问被保护资源了。
在Android应用程序中,则可使用HttpClient来登录系统,
android 连接网络的简单实例
1.android有两种连接网络的类HttpURLConnect和HttpClient,但是HttpClient已逐渐被HttpURLConnect类代替所以就不提及。
2.实例
String address = "http://www.baidu.com"; URL url = new URL(address);//将String类型转化成URL类型 HttpURLConnect con = (HttpURLConnect)url.openConnection();//创建一个指向要访问URL的连接对象。 //注解:但是默认返回的是URLConnect对象。但是我们要连接的是http URL,所以要强制转换成HttpURLConnect。(暂未知URLConnect与Http的关系和区别) //设置请求使用方法 con.setRequestMethod("GET");//GET:希望获取数据,POST:希望发送数据 con.setConnectTimeout(8000);//设置连接超时 con.setReadTimeout(8000);//读取超时 等方法 InputStream is = con.getInputStream();//获取流, if (connection.getResponseCode() != HttpURLConnection.HTTP_OK){ return null; //判断是否连接成功 } //用完之后 is.close();//关闭流 con.disconnect();//关闭http连接
注:只有使用getInputStream()或者getOutputStream()才是真正连接到网络上了
以上是关于HttpClient和HttpURLConnection的区别的主要内容,如果未能解决你的问题,请参考以下文章
Android回顾系列——之HttpUrlConnect的使用
如何使用 HttpUrlConnect 使用 java 查询 Github graphql API
Android探索之HttpURLConnection网络请求