HttpURLConnection和HttpClient比较 :
HttpURLConnection书写时比较繁琐,但运行效率较高
HttpClient书写变的容易,并且便于理解,运行效率不如HttpURLConnection
之前一直在使用HttpClient,但是android 6.0(api 23) SDK,不再提供org.apache.http.*(只保留几个类).所以我们今天主要总结HttpURLConnection的使用。
HttpURLConnection介绍:
HttpURLConnection是一种多用途、轻量极的HTTP客户端,使用它来进行HTTP操作可以适用于大多数的应用程序。对于之前为何一直使用HttpClient而不使用HttpURLConnection也是有原因的。具体分析如下
HttpClient是apache的开源框架,封装了访问http的请求头,参数,内容体,响应等等,使用起来比较方便,而HttpURLConnection是java的标准类,什么都没封装,用起来太原始,不方便,比如重访问的自定义,以及一些高级功能等。
从稳定性方面来说的话,HttpClient很稳定,功能强,BUG少,容易控制细节,而之前的HttpURLConnection一直存在着版本兼容的问题,不过在后续的版本中已经相继修复掉了。
从上面可以看出之前一直使用HttClient是由于HttpURLConnection不稳定导致,那么现在谷歌虽然修复了HttpURLConnection之前存在的一些问题之后,相比HttpClient有什么优势呢?为何要废除HttpClient呢?
HttpUrlConnection是Android SDK的标准实现,而HttpClient是apache的开源实现;
HttpUrlConnection直接支持GZIP压缩;HttpClient也支持,但要自己写代码处理;
HttpUrlConnection直接支持系统级连接池,即打开的连接不会直接关闭,在一段时间内所有程序可共用;HttpClient当然也能做到,但毕竟不如官方直接系统底层支持好;
HttpUrlConnection直接在系统层面做了缓存策略处理,加快重复请求的速度。
HttpURLConnection
GET请求:
public class HttpUtil {
public static byte[] getImage(String URLpath) {
ByteArrayOutputStream baos=null;
InputStream is=null;
try {
// 1.创建URL对象(统一资源定位符) 定位到网络上了
URL url = new URL(URLpath);
// 2.创建连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 3.设置参数
conn.setDoInput(true);// 设置能不能读
conn.setDoOutput(true);// 设置能不能写
conn.setRequestMethod("GET");// 请求方式必须大写
conn.setReadTimeout(5000);// 连接上了读取超时的时间
conn.setConnectTimeout(5000);// 设置连接超时时间5s
// 获取响应码
int code = conn.getResponseCode();
// 4.开始读取
if(code==200){
//5读取服务器资源的流
is= conn.getInputStream();
//准备内存输出流 临时存储的
baos = new ByteArrayOutputStream();
byte buff[] = new byte[1024];
int len=0;
while((len=is.read(buff))!=-1){
baos.write(buff,0,len);
baos.flush();
}
}
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
finally{
//关流
if(is!=null&&baos!=null){
try {
is.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
测试:
public static void main(String[] args) throws Exception {
String url = "https://www.baidu.com/img/bdlogo.png";
//工具类请求完成的字节数组
byte[] image = HttpUtil.getImage(url);
//切割URL字符串得到名字和扩展名
String fileName = url.substring(url.lastIndexOf("/")+1);
File file = new File("c:/image/"+fileName+"");
FileOutputStream fos = new FileOutputStream(file);
fos.write(image);
fos.close();
}
POST请求:
URL url = new URL(path);
// 2.创建连接对象
HttpURLConnection conn = (HttpURLConnection) url.openConnection()
conn.setRequestMethod("POST");//必须大写
// 给服务器写信息 String param是封装了用户名和密码 格式是:user pw
OutputStream os = conn.getOutputStream();
os.write(param.getBytes());
HttpClient
GET请求:
public class HttpUtil {
public static void getImage(final String url, final CallBack callBack) {
new Thread(new Runnable() {
@Override
public void run() {
// 打开一个浏览器
HttpClient client = new DefaultHttpClient();
//在地址栏上输入地址
HttpGet get = new HttpGet(url);
try {
//敲击回车
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
byte[] byteArray = EntityUtils.toByteArray(entity);
//接口用于主函数回调
callBack.getByteImage(byteArray);
}
} catch (Exception e) {
// TODO: handle exception
}
}
}).start();
}
interface CallBack {
void getByteImage(byte[] b);
}
}
测试:
public class URLRequestImage {
public static void main(String[] args) throws Exception {
String url = "https://www.baidu.com/img/bdlogo.png";
HttpUtil.getImage(url, new CallBack() {
@Override
public void getByteImage(byte[] b){
try {
File file = new File("C:/img/a.png");
FileOutputStream fos = new FileOutputStream(file);
fos.write(b);
fos.flush();
System.out.println("图片下载成功");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
POST请求:
HttpPost post = new HttpPost(url);
//定义NameValuePair对象
List<NameValuePair> list = new ArrayList<NameValuePair>();
BasicNameValuePair pair1 = new BasicNameValuePair("userName", "张三");
BasicNameValuePair pair2 = new BasicNameValuePair("userPassword", "123");
//添加到List集合
list.add(pair1);
list.add(pair2);
//
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list);
//设置Post请求entity entity可以理解为大箱子
post.setEntity(entity);
无论那种网络请求GET都是很简单并且很常见的,而POST的请求却很繁琐,HttpURLconnection用流向服务器里写,HttpClient是给HttpPost引用setEntity。
文件下载:
private void downloadFile(String fileUrl){
try {
// 新建一个URL对象
URL url = new URL(fileUrl);
// 打开一个HttpURLConnection连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 设置连接主机超时时间
urlConn.setConnectTimeout(5 * 1000);
//设置从主机读取数据超时
urlConn.setReadTimeout(5 * 1000);
// 设置是否使用缓存 默认是true
urlConn.setUseCaches(true);
// 设置为Post请求
urlConn.setRequestMethod("GET");
//urlConn设置请求头信息
//设置请求中的媒体类型信息。
urlConn.setRequestProperty("Content-Type", "application/json");
//设置客户端与服务连接类型
urlConn.addRequestProperty("Connection", "Keep-Alive");
// 开始连接
urlConn.connect();
// 判断请求是否成功
if (urlConn.getResponseCode() == 200) {
String filePath="";
File descFile = new File(filePath);
FileOutputStream fos = new FileOutputStream(descFile);;
byte[] buffer = new byte[1024];
int len;
InputStream inputStream = urlConn.getInputStream();
while ((len = inputStream.read(buffer)) != -1) {
// 写到本地
fos.write(buffer, 0, len);
}
} else {
Log.e(TAG, "文件下载失败");
}
// 关闭连接
urlConn.disconnect();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
文件上传:
处理网络流:将输入流转换成字符串:
附:封装HttpURLConnection网络请求 Get请求:
封装HttpURLConnection网络请求 Post请求: