HttpClient和HttpURLConnection的区别

发布网友 发布时间:2022-04-20 02:15

我来回答

3个回答

懂视网 时间:2022-05-13 13:17

??

  1. 编写如下项目:

2 编写Android清单文件

package="com.itheima28.htmldemo"

android:versionCode="1"

android:versionName="1.0" >

android:minSdkVersion="8"

android:targetSdkVersion="19" />

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

android:name="com.itheima28.htmldemo.MainActivity"

android:label="@string/app_name" >

3 编写布局文件activity_main.xml

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context=".MainActivity" >

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/et_url"

android:layout_width="0dip"

android:text="http://www.baidu.com"

android:layout_height="wrap_content"

android:singleLine="true"

android:layout_weight="1"/>

4 编写Activity的类MainActivity如下:

package com.itheima28.htmldemo;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.text.TextUtils;

import android.util.Log;

import android.view.View;

import android.widget.EditText;

import android.widget.TextView;

import android.widget.Toast;

public class MainActivity extends Activity {

private static final String TAG = "MainActivity";

private static final int SUCCESS = 0;

protected static final int ERROR = 1;

private EditText etUrl;

private TextView tvHtml;

private Handler handler = new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

switch (msg.what) {

case SUCCESS:

tvHtml.setText((String) msg.obj);

break;

case ERROR:

Toast.makeText(MainActivity.this, "访问失败", 0).show();

break;

default:

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

etUrl = (EditText) findViewById(R.id.et_url);

tvHtml = (TextView) findViewById(R.id.tv_html);

}

public void getHtml(View v) {

final String url = etUrl.getText().toString();

new Thread(new Runnable() {

@Override

public void run() {

// 请求网络

String html = getHtmlFromInternet(url);

if(!TextUtils.isEmpty(html)) {

// 更新textview的显示了

Message msg = new Message();

msg.what = SUCCESS;

msg.obj = html;

handler.sendMessage(msg);

} else {

Message msg = new Message();

msg.what = ERROR;

handler.sendMessage(msg);

}

}

}).start();

}

/**

* 根据给定的url访问网络, 抓去html代码

* @param url

* @return

*/

protected String getHtmlFromInternet(String url) {

try {

URL mURL = new URL(url);

HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(10000);

conn.setReadTimeout(5000);

// conn.connect();

int responseCode = conn.getResponseCode();

if(responseCode == 200) {

InputStream is = conn.getInputStream();

String html = getStringFromInputStream(is);

return html;

} else {

Log.i(TAG, "访问失败: " + responseCode);

}

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

/**

* 根据流返回一个字符串信息

* @param is

* @return

* @throws IOException

*/

private String getStringFromInputStream(InputStream is) throws IOException {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len = -1;

while((len = is.read(buffer)) != -1) {

baos.write(buffer, 0, len);

}

is.close();

String html = baos.toString(); // 把流中的数据转换成字符串, 采用的编码是: utf-8

String charset = "utf-8";

if(html.contains("gbk") || html.contains("gb2312")

|| html.contains("GBK") || html.contains("GB2312")) { // 如果包含gbk, gb2312编码, 就采用gbk编码进行对字符串编码

charset = "gbk";

}

html = new String(baos.toByteArray(), charset); // 对原有的字节数组进行使用处理后的编码名称进行编码

baos.close();

return html;

}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

热心网友 时间:2022-05-13 10:25

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();
}
}
}

热心网友 时间:2022-05-13 11:43

大多数的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来登录系统,
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com