Android的HTTP请求方式
前言
大多数网络连接的Android应用程序都将使用HTTP发送和接收数据对于Http协议的工作原理,一句话概括的话,就是客户端向服务器发出一条HTTP请求,服务器收到之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。
一、HTTP协议的主要特点:
支持客户/服务器模式
简单快速:客户向服务端请求服务时,只需传送请求方式和路径。
灵活:允许传输任意类型的数据对象。由Content-Type加以标记。
无连接:每次响应一个请求,响应完成以后就断开连接。
无状态:服务器不保存浏览器的任何信息。每次提交的请求之间没有关联
持续性: 浏览器和服务器建立TCP连接后,可以请求多个对象
非持续性: 浏览器和服务器建立TCP连接后,只能请求一个对象
二、一些需要注意的问题
1.POST和GET的区别
Post一般用于更新或者添加资源信息 Get一般用于查询操作,而且应该是安全和幂等的
Post更加安全 Get会把请求的信息放到URL的后面
Post传输量一般无大小限制 Get不能大于2KB
Post执行效率低 Get执行效率略高
2.为什么POST效率低,Get效率高?
Get将参数拼成URL,放到header消息头里传递
Post直接以键值对的形式放到消息体中传递。
但两者的效率差距很小很小。
Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient.两者都支持HTTPS,流式传输上传和下传,可配置超时,IPv6和连接池
不过由于HttpClient存在的API数量过多,扩展困难等缺陷,在开发中也不会推荐使用这种方式。因此在Android M(6.0版本)系统中,HttpClient的功能被完全移除了,标志着此功能被正式弃用,所以今天就介绍一下现在官方建议使用HttpURLConnection的用法.
HttpURLConnection是适用于大多数应用程序的通用轻量级的HTTP客户端,这个阶段发展较为稳重缓慢,但是它的重点API能使我们能够轻松地改进。
三、详细过程
首先需要获取到HttpURLConnection的实例,一般只需要new 出一个URL对象,并传入目标的网络地址,然后调用一下openConnection()方法即可,
URL url = new URL("http://blog.csdn.net/checkiming"); HttpURLConnection connection = (HttpURLConnection)url.openConnection();
在得到了HttpURLConnection的实例之后,可以设置一下HTTP请求所使用的方法。常用的两个方法为: POST和GET .GET表示希望从服务器那里获取到数据,而POST则表示希望提交数据给服务器。
connection.setRequestMethod("GET")
connection.setRequestMethod("POST")
接下来就可以进行一些自由的定制了,比如设置连接超时、读取超时的毫秒数,以及服务器希望得到的一些消息头等,这部分是可以根据自己的需求情况写的,示例:
connection.setConnectTimeout(6000);
connection.setReadTimeout(6000);
之后再调用getInputStream()方法就可以获取到服务器返回的输入流了,剩下的任务就是对输入流进行读取,如下所示:
InputStream in = connection.getInputStream();
最后可以调用disconnect()这个方法将这个HTTP连接关闭掉,如下显示
connection.disconnect();
即使Google在大部分Android版本推荐建议使用HttpURLConnection ,但在开源盛行的今天,我们完全可以使用一些出色的网络通信库来替代原生的HttpURLConnection ,而OkHttp也是最出色的一个。
Okhttp介绍
OkHttp是一个高效的Http客户端,有如下的特点:
支持HTTP2/SPDY黑科技
socket自动选择最好路线,并支持自动重连
拥有自动维护的socket连接池,减少握手次数
拥有队列线程池,轻松写并发
拥有Interceptors轻松处理请求与响应(比如透明GZIP压缩,LOGGING)
基于Headers的缓存策略
之前也有说到,OKhttp是一个相对成熟的解决方案,在Android4.4的源码中已经将HttpURLConnection替换成了OKhttp,所以我们更有理由去相信OKhttp的强大之处.
OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。
使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和java.net.HttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。
get参数
// 定义okhttp OkHttpClient okHttpClient_get = new OkHttpClient();// 02.请求体 Request request = new Request.Builder() .get()//get请求方式 .url("http://10.0.3.2:8080/WebServiceTest/servlet/ServcieTest?name=sy")//网址 .build(); Response response = okHttpClient_get.newCall(request).execute();if (response.isSuccessful()) { // 打印数据 System.out.println(response.body().string()); } else { throw new IOException("Unexpected code " + response); }
post请求参数
// 定义okhttp OkHttpClient okHttpClient_post_kv = new OkHttpClient(); // 定义请求体 // 执行okhttp RequestBody body = new FormBody.Builder() .add("name", "sy")//添加参数体 .add("age", "18") .build(); Request request = new Request.Builder() .post(body) //请求参数 .url("http://10.0.3.2:8080/WebServiceTest/servlet/ServcieTest") .build(); Response response = okHttpClient_post_kv.newCall(request).execute(); System.out.println(response.body().string());
post请求json
OkHttpClient okHttpClient_post_json = new OkHttpClient(); String json = "{\n" + " "age": "18",\n" + " "name": "sy"\n" + "}"; RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), json); Request request = new Request.Builder().post(body).url("http://10.0.3.2:8080/WebServiceTest/servlet/ServcieTest").build(); Response response = okHttpClient_post_json.newCall(request).execute(); System.out.println(response.body().string());
上传图片
OkHttpClient okHttpClient_upload = new OkHttpClient(); File file = new File(Environment.getExternalStorageDirectory() + "/download", "file.txt"); RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), file); Request request = new Request.Builder() .post(body) .url("http://10.0.3.2:8080/WebServiceTest/servlet/ServcieTest") .build(); Response response = okHttpClient_upload.newCall(request).execute(); System.out.println(response.body().string());
下载图片
OkHttpClient okHttpClient_down = new OkHttpClient(); Request request = new Request.Builder().get().url("http://10.0.3.2:8080/WebServiceTest/p22.jpg").build(); okHttpClient_down.newCall(request).enqueue(MainActivity.this);
Call对象
Call call=client.newCall(request); //获取Call对象 Response response=call.execute(); //同步执行网络请求,不要在主线程执行 call.enqueue(new Callback()); //异步执行网络请求 call.cancel(); //取消请求 call.isCanceled(); //查询是否取消 call.isExecuted(); //查询是否被执行过 ResponseBody body.contentLength(); //body的长度 String content=body.string(); //以字符串形式解码body byte[] byteContent=body.bytes(); //以字节数组形式解码body InputStreamReader reader=body.charStream(); //将body以字符流的形式解码 InputStream inputStream=body.byteStream(); //将body以字节流的形式解码