什么是OkHttp
OKhttp是一个处理网络请求的开源项目,它主要的优势有:
1.允许连接到同一个主机地址的所有请求,提高请求效率
2. 共享Socket,减少对服务器的请求次数
3.通过连接池,减少了请求延迟
4.缓存响应数据来减少重复的网络请求
5.减少了对数据流量的消耗
6.自动处理GZip压缩
-----------------------------------------------------------------------以上信息摘自百度
那么有人会问,OkHttp和HttpClient有什么不同?这里我推荐一下这篇文章:HTTP客户端连接,选择HttpClient还是OkHttp?,这篇文章对比了一下两者的区别,其实实际上的性能差异并不是太大,各位可以根据自己的喜好使用,不必纠结于此。
这里顺便附上OkHttp官网地址:OkHttp官网
这是GitHub地址:OkHttp GitHub地址
准备
好了,接下来进入正题,因为我用的是maven,所以需要在pom.xml中添加下面代码:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.2.0</version>
</dependency>
我这里用的是3.2.0,如果出现java.lang.NoClassDefFoundError: kotlin/TypeCastException可以尝试更换下其他版本,并且把okio-1.13.0.jar下载下来添加到依赖中。
OkHttp配置
环境准备好了就开始写代码啦
public class OkHttpLearn {
private final OkHttpClient okHttpClient;
// 初始化
private OkHttpLearn(){
okHttpClient = new OkHttpClient.Builder()
// 设置连接超时时间,这里是一分钟
.connectTimeout(60, TimeUnit.SECONDS)
// 设置读取超时时间, 这里是一分钟
.readTimeout(60, TimeUnit.SECONDS)
// 设置写入超时时间, 这里是一分钟
.writeTimeout(60, TimeUnit.SECONDS)
.build();
}
}
GET请求
同步有/无请求头
同步时线程会进行阻塞,直到消息返回才会继续执行。
/**
* 无请求头
*
* @param url
* @return
* @throws IOException
*/
public ResponseBody get(String url) throws IOException {
Request request = new Request.Builder().url(url).build();
return okHttpClient.newCall(request).execute().body();
}
/**
* 有请求头
* @param url
* @param headers
* @return
*/
public ResponseBody get(String url, Map<String, Object> headersMap) throws IOException {
Request.Builder request = new Request.Builder()
.url(url);
for (Map.Entry<String, Object> header : headersMap.entrySet()) {
request.addHeader(header.getKey(), String.valueOf(header.getValue()));
}
return okHttpClient.newCall(request.build()).execute().body();
}
Request包含消息请求体、消息体等等,get请求的话不需要将参数存在消息体。
Response则是服务端响应的消息体,可以在这里获取返回结果。
异步GET请求
/**
* 异步请求
* @param url
* @param headers
* @return
*/
public void getAsyn(String url) throws IOException {
Request.Builder request = new Request.Builder()
.url(url);
Call call = okHttpClient.newCall(request.addHeader("bearea", "this is async request").build());
call.request();
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("请求失败");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println(response.body().string());
}
});
}
异步请求比起同步请求要方便,不会影响客户体验。
测试代码
public static void main(String[] args) throws IOException {
OkHttpLearn okHttpLearn = new OkHttpLearn();
Map<String, Object> map = new HashMap<>();
map.put("bearea", "hello");
ResponseBody responseBody = okHttpLearn.get("http://localhost:8080/test2");
// 这是有请求头
ResponseBody responseBody2 = okHttpLearn.get("http://localhost:8080/test2", map);
System.out.println(responseBody.string() + " " + responseBody2.string());
}
结果
POST请求
说完GET请求,让我们来看看POST请求,POST请求和GET请求在构造Request差不多,只不过多了method()方法
Request builder = new Request.Builder()
.url(url)
.method("POST", requestBody)
.build();
method(method(String method, RequestBody body)方法的两个参数,一个是请求方法类型,这里有POST、PUT、DELETE,而RequestBody是请求消息体,里面封装了需要传输的数据,具体用法如下:
public ResponseBody post(String url) throws IOException {
RequestBody requestBody = new FormBody.Builder()
.add("name", "okhttp")
.add("age", "15")
.build();
Request builder = new Request.Builder()
.url(url)
.method("POST", requestBody)
.build();
return okHttpClient.newCall(builder).execute().body();
}
当然啦,以上是同步调用,如果想异步调用的话可以参照GET请求的异步调用方法,我这里就不重复说了。
对于RequestBody有几种类型:
- 如果你想传输JSON串,可以这样做:
RequestBody requestBody = RequestBody.create(MediaType.parse(“text/plain;charset=utf-8”), “{username:admin;password:admin}”); - 如果想上传文件,就这样做:
RequestBody requestBody2 = RequestBody.create(MediaType.parse(“application/octet-stream”), file); file为File类型
测试
现在我们来测试一下:
public static void main(String[] args) throws IOException {
OkHttpLearn okHttpLearn = new OkHttpLearn();
ResponseBody responseBody = okHttpLearn.post("http://localhost:8080/test3");
System.out.println(responseBody.string());
}
结尾
OkHttp总体用起来和HttpClient没有太过特别的地方,但是在发送请求方面我觉得还是比HttpClient方便一点,具体情况还是看个人。当然啦,用法还有很多,我这里列出的只是一小部分,想深入理解的话可以到OkHttp官网看下,我上面已经有链接了。