OKHttp3学习
转载 Okhttp3基本使用 基本使用——OkHttp3详细使用教程
一、简介
HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。
OkHttp是一个高效的HTTP客户端,它有以下默认特性:
- 支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接
- 连接池减少,请求连接复用以提高效率
- 透明的GZIP压缩减少响应数据的大小
- 缓存响应内容,避免一些完全重复的请求
- 当网络出现问题时,OkHttp 会自动重试一个主机的多个 IP 地址
当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。
注:
- OkHttp 支持 Android 2.3 及以上版本Android平台, 对于 Java, JDK 1.7及以上.。
- socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
二、使用例子:
讲解:
Requests-请求:
每一个HTTP请求中都应该包含一个URL,一个GET或POST方法以及Header或其他参数,当然还可以含特定内容类型的数据流。request一旦build()之后,便不可修改。
Responses-响应:
响应则包含一个回复代码(200代表成功,404代表未找到),Header和定制可选的body。
OkHttpClient:
OkHttpClient可以发送一个Http请求,并读取该Http请求的响应,它是一个生产Call的工厂。 此外,受益于一个共享的响应缓存/线程池/复用的连接等因素,绝大多数应用使用一个OkHttpClient实例,便可以满足整个应用的Http请求。
三种创建实例的方法:
- 创建一个默认配置OkHttpClient,可以使用默认的构造函数。
- 通过new OkHttpClient.Builder()方法来一步一步配置一个OkHttpClient实例。
- 如果要求使用现有的实例,可以通过newBuilder()方法来进行构造。
OkHttpClient client = new OkHttpClient();
OkHttpClient clientWith30sTimeout = client.Builder()
.readTimeout(30, TimeUnit.SECONDS)
.build();
OkHttpClient client = client.newBuilder().build();
1.get请求方式
1.1 get异步提交请求
/**
* get异步提交请求
* @param url
*/
public static void getAsyn(String url) {
// 1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
// 2.创建Request对象,设置一个url地址,设置请求方式。默认为get请求,可以不写。
final Request request = new Request.Builder()
.url(url)
.get()
.build();
// 3.创建一个call对象,参数就是Request请求对象
Call call = okHttpClient.newCall(request);
// 4.请求加入调度,重写回调方法
call.enqueue(new Callback() {
// 请求失败执行的方法
@Override
public void onFailure(Call call, IOException e) {
logger.info("getAsyn-call"+call);
logger.info("getAsyn-IOException:"+e);
}
// 请求成功执行的方法
@Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("getAsyn-response:"+response);
System.out.println(response.body().string());
System.out.println(response.body().byteStream());
logger.info("call"+call);
}
});
}
1.2 get同步提交请求
/**
* get同步提交请求
* @param url
*/
public static void getSyn(String url) {
// 1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
// 2.创建Request对象,设置一个url地址,设置请求方式。
final Request request = new Request.Builder().url(url).build();
// 3.创建一个call对象,参数就是Request请求对象
final Call call = okHttpClient.newCall(request);
// 4.同步调用会阻塞主线程,这边在子线程进行
new Thread(new Runnable() {
@Override
public void run() {
try {
// 同步调用,返回Response,会抛出IO异常
Response response = call.execute();
logger.info("getSyn-response:"+response);
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
1.3 get异步下载文件
/**
* get异步下载文件
* @param url
*/
public static void getFile(String url) {
// 1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
// 2.创建Request对象,设置一个url地址,设置请求方式。
Request request = new Request.Builder()
.url(url)
.get()
.build();
// 3.创建一个call对象,参数就是Request请求对象,重写回调方法。
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("getFile-call"+call);
logger.info("getFile-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
// 拿到字节流
InputStream is = response.body().byteStream();
int len = 0;
// 设置下载图片存储路径和名称
File file = new File("F:/img/","baidu.png"); FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[128];
while ((len = is.read(buf)) != -1) {
fos.write(buf,0,len);
}
fos.flush();
fos.close();
is.close();
}
});
}
2.post请求方式
2.1 post异步请求String
/**
* post异步请求String
* @param url
*/
public static void postString(String url) {
// "类型,字节码"
MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
// 1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
String requestBody = "{name:nana}";
// 3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(mediaType,requestBody))
.build(); // 4.创建一个call对象,参数就是Request请求对象。请求加入调度,重写回调方法
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("postString-call"+call);
logger.info("postString-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postString-response:"+response);
System.out.println(response.body().string());
System.out.println(response.body().byteStream());
logger.info("postString-call"+call);
}
});
}
2.2 post异步请求流
/**
* post异步请求流
* @param url
*/
public static void postStreaming(String url) {
final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");
File file = new File("F:/img/baidu.png");
try {
FileInputStream fileInputStream = new FileInputStream(file); RequestBody requestBody = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MEDIA_TYPE_MARKDOWN;
} @Override
public void writeTo(BufferedSink bufferedSink) throws IOException {
OutputStream outputStream = bufferedSink.outputStream();
int length = 0;
byte[] buffer = new byte[1024];
while ((length = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer,0,length);
}
}
};
Request request = new Request.Builder().
url(url).
post(requestBody).
build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).enqueue(new Callback() { @Override
public void onFailure(Call call, IOException e) {
logger.info("postFlow-call"+call);
logger.info("postFlow-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postFlow-response:"+response);
logger.info(response.protocol()+" "+response.code() + " " + response.message());
Headers headers = response.headers();
for (int i=0;i< headers.size();i++) {
System.out.println(headers.name(i)+":"+headers.value(i));
}
System.out.println(response.body().string());
logger.info("postFlow-call"+call);
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} }
2.3 post异步上传Multipart文件
/**
* post异步上传Multipart文件
* @param url
*/
public static void postMultipart(String url) {
OkHttpClient okHttpClient = new OkHttpClient();
File file = new File("F:/img/","baidu.png");
MediaType mediaType = MediaType.parse("image/png");
RequestBody requestBody = new MultipartBody.Builder()
// 设置表单类型
.setType(MultipartBody.FORM)
// 添加数据
.addFormDataPart("name","nana")
.addFormDataPart("file","baidu.png",RequestBody.create(mediaType,file))
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("postFlow-call"+call);
logger.info("postFlow-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postMultiportBody-response:"+response);
System.out.println(response.body().string());
logger.info("postMultiportBody-call"+call);
}
});
}
2.4 post异步请求文件
/**
* post异步请求文件
* @param url
*/
public static void postFile(String url) {
MediaType mediaType = MediaType.parse("text/x-markdown;charset=utf-8");
OkHttpClient okHttpClient = new OkHttpClient();
File file = new File("F:/img/baidu.png");
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(mediaType,file))
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("postFile-call"+call);
logger.info("postFile-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postFile-response:"+response);
logger.info(response.protocol()+" "+response.code() + " " + response.message());
Headers headers = response.headers();
for (int i=0;i< headers.size();i++) {
System.out.println(headers.name(i)+":"+headers.value(i));
}
System.out.println(response.body().string());
System.out.println(response.body().byteStream());
logger.info("postFile-call"+call);
}
});
}
2.5 post异步请求表单
/**
* post异步请求表单
* @param url
*/
public static void postForm(String url) {
// 1.创建OkHttpClient对象
OkHttpClient okHttpClient = new OkHttpClient();
// 2.通过new FormBody()调用build方法,创建一个RequestBody,可以用add添加键值对
RequestBody requestBody = new FormBody.Builder()
.add("name","nana")
.build();
// 3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
// 4.创建一个call对象,参数就是Request请求对象。请求加入调度,重写回调方法
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
if(e.toString().contains("closed")) {
// 主动取消的请情况下
}
logger.info("postForm-call"+call);
logger.info("postForm-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postForm-response:"+response);
logger.info(response.protocol()+" "+response.code() + " " + response.message());
Headers headers = response.headers();
for (int i=0;i< headers.size();i++) {
System.out.println(headers.name(i)+":"+headers.value(i));
}
System.out.println(response.body().string());
System.out.println(response.body().byteStream());
logger.info("postForm-call"+call);
}
});
}
2.6 post异步请求表单
/**
* post分块请求
* @param url
*/
public static void postMultiportBody(String url) {
final String IMGUR_CLIENT_ID = "...";
final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
OkHttpClient client = new OkHttpClient();
MultipartBody body = new MultipartBody.Builder("Axad")
.setType(MultipartBody.FORM)
.addPart(
Headers.of("Content-Disposition","form-data;name='name'"),
RequestBody.create(null,"nana")
)
.addPart(
Headers.of("Content-Dispostion","form-data;name='image'"),
RequestBody.create(MEDIA_TYPE_PNG,new File("img.png"))
)
.build();
Request request = new Request.Builder()
.header("Authorization","Client-ID "+IMGUR_CLIENT_ID)
.url(url)
.build(); Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("postMultiportBody-call"+call);
logger.info("postMultiportBody-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postMultiportBody-response:"+response);
System.out.println(response.body().string());
logger.info("postMultiportBody-call"+call);
}
});
}
2.7 post拦截器
/**
* post拦截器
* @param url
*/
public static void postInterceptor(String url) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new LoggerInterceptor())
.build();
Request request = new Request.Builder()
.url(url)
.header("User-Agent","OKHttp Example")
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
logger.info("postInterceptor-call"+call);
logger.info("postInterceptor-IOException:"+e);
} @Override
public void onResponse(Call call, Response response) throws IOException {
logger.info("postInterceptor-response:"+response);
ResponseBody body = response.body();
if (body != null) {
System.out.println(response.body().string());
body.close();
}
logger.info("postInterceptor-call:"+call);
}
});
}
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.IOException; public class LoggerInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggerInterceptor.class);
private static final String TAG = "LoggingInterceptor";
@Override
public Response intercept(Chain chain) throws IOException {
// 拦截请求,获取到该次请求的request
Request request = chain.request(); long startTime = System.nanoTime();
logger.info(String.format("Sending request %s on %s%n%s",
request.url(),chain.connection(),request.headers()));
// 执行本次网络请求操作返回response
Response response = chain.proceed(request);
long endTime = System.nanoTime();
logger.info(String.format("Received response for %s in %.1fms%n%s",
response.request().url(),(endTime - startTime)/1e6d,response.headers()));
return response;
}
}
OKHttp3学习的更多相关文章
- Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava
Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava Retrofit,因为其简单与出色的性能,也是受到很多人的青睐,但是他和以往的通信 ...
- JAVA学习笔记 (okHttp3的用法)
最近的项目中有个接口是返回文件流数据,根据我们这边一个验签的插件,我发现里面有okHttpClient提供了Call.Factory,所以就学习了下okHttp3的用法. 1.概述 okhttp是一个 ...
- Android 框架学习之 第一天 okhttp & Retrofit
最近面试,一直被问道新技术新框架,这块是短板,慢慢补吧. 关于框架的学习,分几个步骤 I.框架的使用 II.框架主流使用的版本和Android对应的版本 III.框架的衍生使用比如okhttp就会有R ...
- 【Android】OkHttp3总结与封装
开始使用 在app目录下的build.gradle中添加依赖: implementation 'com.squareup.okhttp3:okhttp:3.13.1' implementation ' ...
- Android 技能图谱学习路线
这里是在网上找到的一片Android学习路线,希望记录下来供以后学习 1Java 基础 Java Object类方法 HashMap原理,Hash冲突,并发集合,线程安全集合及实现原理 HashMap ...
- Android开发技术周报176学习记录
Android开发技术周报176学习记录 教程 当 OkHttp 遇上 Http 2.0 http://fucknmb.com/2018/04/16/%E5%BD%93OkHttp%E9%81%87% ...
- springcloud Ribbon学习笔记二
之前介绍了如何搭建eureka服务并开发了一个用户服务成功注册到了eureka中,接下来介绍如何通过ribbon来从eureka中获取用户服务: springcloud ribbon提供客户端的负载均 ...
- Android学习之基础知识十二 — 第二讲:网络编程的最佳实践
上一讲已经掌握了HttpURLConnection和OkHttp的用法,知道如何发起HTTP请求,以及解析服务器返回的数据,但是也许你还没发现,之前我们的写法其实是很有问题的,因为一个应用程序很可能会 ...
- android-------- 常用且应该学习的框架
今天来分享一下一些常用的库,在Github 上 star数也是很高的,开发中也是很常用的: 简单的分享一下,一起学习. http://www.xiufm.com/blog-1-944.html 框架名 ...
随机推荐
- 撩课-Java每天10道面试题第5天
41.Iterator.ListIterator 和 Enumeration的区别? 迭代器是一种设计模式, 它是一个对象, 它可以遍历并选择序列中的对象, 而开发人员不需要了解 该序列的底层结构. ...
- js历史记录
1. history 是什么? window上的一个对象,由来存储浏览器访问过的历史 2. 用途: 可以动态跳转任意一个已在历史记录中的地址 3..history方法: 1.forward() : 向 ...
- csharp: string Encoding
/// <summary> /// 中文转unicode /// </summary> /// <param name="str"></p ...
- JavaScript周报#183
This week’s JavaScript news Read this issue on the Web | Issue Archive JavaScript Weekly Issue 183Ma ...
- 什么是首字节时间(TTFB)
第一字节响应时间(TTFB)=从发送请求到WEB服务器的时间+WEB服务器处理请求并生成响应花费的时间+WEB服务器生成响应到浏览器花费的时间测量第一字节响应时间(TTFB)的工具:http://ww ...
- Java 之集合框架 上(9)
Java 中的集合框架 如果一个类中存在很多相同类型的属性. 例如:学生类 学生可以选课,因此存在很多课程类型的属性.但是每个学生选择的课程的种类和数量是不一样的. 如果将每一个课程类型的属性都列到课 ...
- The difference between a local variable and a member variable
package com.itheima_04; /* * 成员变量和局部变量的区别: * A:在类中的位置不同 * 成员变量:类中,方法外 * 局部变量:方法中或者方法声明上(形式参数) * B:在内 ...
- integer storage and decimal storage differences in java
package storage.java; public class StorageJava { public static void main(String[] args) { byte b = 1 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(4)、基于Android Studio构建ArcGIS Android开发环境
1.前言 2015年1月15日,发布ArcGIS Runtime SDK for Android v10.2.5版本.从该版本开始默认支持android studio开发环境,示例代码的默认开发环境也 ...
- Appium元素定位(uiautomatorviewer)
一.uiautomatorviewer元素定位 1.adroid-sdk的安装目录tools下有1个自带的工具uiautomatorviewer,打开后,如下所示: 点击后,如图所示: 步骤: a.链 ...