OkHttp 官方Wiki之【使用案例】
Recipes 食谱/知识点清单
我们编写了一些食谱,演示如何解决使用OkHttp时常见的问题。 阅读他们,了解一切是如何一起工作。 自由剪切并粘贴这些例子,这就是他们的目的。
Synchronous Get 同步Get
Download a file, print its headers, and print its response body as a string.
下载一个文件,打印它的响应结果的响应头,并以字符串形式将它的响应体打印出来。
The string() method on response body is convenient and efficient for small documents. But if the response body is large (greater than 1 MiB), avoid string() because it will load the entire document into memory. In that case, prefer to process the body as a stream.
响应体中的string()方法对于小文档来时是方便和高效的。但是如果响应体很大(大于1Mib),则应避免使用string()方法,因为它将把整个文档加载到内存中。在这种情况下,可以将响应体作为流来处理。
public void synchronousGet() throws Exception {
Request request = new Request.Builder()//Get请求
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();//同步请求
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);//响应失败
Headers responseHeaders = response.headers();//响应头
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println("【" + responseHeaders.name(i) + "】" + responseHeaders.value(i));
}
System.out.println("【响应结果】" + response.body().string());//响应体
}
Asynchronous Get 异步Get
Download a file on a worker thread, and get called back when the response is readable. The callback is made after the response headers are ready. Reading the response body may still block. OkHttp doesn't currently offer asynchronous APIs to receive a response body in parts.
在工作线程上下载一个文件,并在响应可读时调用。回调是在响应头准备好之后进行的。读取响应体可能仍然会阻塞。OkHttp当前不提供异步API以部分接收响应主体。
public void asynchronousGet() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {//异步请求
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println("【" + responseHeaders.name(i) + "】" + responseHeaders.value(i));
}
System.out.println("【响应结果】" + response.body().string());
}
});
}
Accessing Headers 访问头信息
public void accessingHeaders() throws Exception {
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")//使用 header 会移除已经存在的头
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")//使用 addHeader 不会移除已经存在的头
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
//访问Header
System.out.println("【Server】" + response.header("Server"));
System.out.println("【Date】" + response.header("Date"));
System.out.println("【Vary】" + response.headers("Vary"));
}
Posting a String 以Post发送字符串
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
public void postString() throws Exception {
String postBody = ""
+ "Releases\n"
+ "--------\n"
+ "\n"
+ " * _1.0_ May 6, 2013\n"
+ " * _1.1_ June 15, 2013\n"
+ " * _1.2_ August 11, 2013\n";
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))//以Post发送字符串,字符串是MARKDOWN文件中的内容
.build();
}
Post Streaming 以Post发送流
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
public void postStreaming() throws Exception {
RequestBody requestBody = new RequestBody() {
@Override
public MediaType contentType() {
return MEDIA_TYPE_MARKDOWN;//内容类型为:MARKDOWN媒体文件
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
sink.writeUtf8("Numbers\n");
sink.writeUtf8("-------\n");
for (int i = 2; i <= 997; i++) {
sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i)));
}
}
private String factor(int n) {
for (int i = 2; i < n; i++) {
int x = n / i;
if (x * i == n) return factor(x) + " × " + i;
}
return Integer.toString(n);
}
};
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(requestBody)//以Post发送流
.build();
}
Posting a File 以Post发送文件
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
public void postFile() throws Exception {
File file = new File(Environment.getExternalStorageDirectory(), "README.md");
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))//以Post发送文件
.build();
}
Posting form parameters 以Post发送表单参数
public void postFormParameters() throws Exception {
RequestBody formBody = new FormBody.Builder()
.add("search", "Jurassic Park")
.build();
Request request = new Request.Builder()
.url("https://en.wikipedia.org/w/index.php")
.post(formBody)//以Post发送表单参数
.build();
}
Posting a multipart request 以Post发送多请求体的请求
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
public void postMultipartRequest() throws Exception {
RequestBody partRequestBody = RequestBody.create(MEDIA_TYPE_PNG, new File(Environment.getExternalStorageDirectory(), "logo.png"));
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "Square Logo")
.addFormDataPart("image", "logo-square.png", partRequestBody)//多部分请求体的每个部分本身就是一个请求体
.build();
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + "...")
.url("https://api.imgur.com/3/image")
.post(requestBody)//以Post发送多请求体的请求
.build();
}
Parse a JSON Response With Gson/Moshi 使用Gson/Moshi来解析JSON响应
private final Moshi moshi = new Moshi.Builder().build();
public void parseJSONResponseWithGson() throws Exception {
Request request = new Request.Builder()
.url("https://api.github.com/gists/c2a7c39532239ff261be")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Gist gist = new Gson().fromJson(response.body().charStream(), Gist.class);//使用Gson来解析JSON响应
Gist gist2 = moshi.adapter(Gist.class).fromJson(response.body().source());//使用Moshi来解析JSON响应
for (Map.Entry<String, Gist.GistFile> entry : gist.files.entrySet()) {
System.out.println("【Key】" + entry.getKey());
System.out.println("【Value】" + entry.getValue().content);
}
}
static class Gist {
Map<String, GistFile> files;
}
static class GistFile {
String content;
}
Response Caching 缓存响应
要缓存响应,您将需要一个可以读取和写入的缓存目录,并对缓存大小进行限制。 缓存目录应该是私有的,不受信任的应用程序不能读取其内容!
让多个缓存同时访问同一缓存目录是一个错误。 大多数应用程序都应该只调用一次 new OkHttpClient(),配置它们的缓存,并在任何地方使用相同的实例。 否则两个缓存实例将彼此踩踏(相互影响),损坏响应缓存,并可能会导致程序崩溃。
public void responseCaching() throws Exception {
File cacheFile = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), "cache");//缓存路径
Cache cache = new Cache(cacheFile, 10 * 1024 * 1024);//缓存大小10 MiB
client = new OkHttpClient.Builder()
.cache(cache)//缓存响应
.build();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
String response1Body = response1.body().string();
System.out.println("【Response 1 response】" + response1);
System.out.println("【Response 1 cache response】" + response1.cacheResponse());
System.out.println("【Response 1 network response】" + response1.networkResponse());
Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
String response2Body = response2.body().string();
System.out.println("【Response 2 response】" + response2);
System.out.println("【Response 2 cache response】" + response2.cacheResponse());
System.out.println("【Response 2 network response】" + response2.networkResponse());
System.out.println("【两次响应结果是否相同】" + response1Body.equals(response2Body));
}
Canceling a Call 取消一个请求
public void cancelingCall() throws Exception {
Request request = new Request.Builder()
.url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay. 此网址延迟2秒后才处理请求。
.build();
final long startNanos = System.nanoTime();
final Call call = client.newCall(request);
// Schedule a job to cancel the call in 1 second. 在1秒内安排一个作业取消请求。
Executors.newScheduledThreadPool(1).schedule(() -> {
System.out.printf("【取消前】%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f);
call.cancel();//取消一个请求
System.out.printf("【取消后】%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f);
}, 1, TimeUnit.SECONDS);
try {
System.out.printf("【读取响应前】%.2f Executing call.%n", (System.nanoTime() - startNanos) / 1e9f);
Response response = call.execute();
System.out.printf("【读取响应后】%.2f Call was expected to fail, but completed: %s%n", (System.nanoTime() - startNanos) / 1e9f, response);
} catch (IOException e) {
System.out.printf("【正在读取响应时取消请求会收到一个异常】%.2f Call failed as expected: %s%n", (System.nanoTime() - startNanos) / 1e9f, e);
}
}
Timeouts 超时
public void settTmeouts() throws Exception {
client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)//连接超时时间
.writeTimeout(10, TimeUnit.SECONDS)//写入超时时间
.readTimeout(500, TimeUnit.MILLISECONDS)//读取超时时间
.build();
Request request = new Request.Builder()
.url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
.build();
Response response = client.newCall(request).execute();
System.out.println("【响应结果】" + response.body().string());
}
Per-call Configuration 预配置
public void perCallConfiguration() throws Exception {
OkHttpClient copyClient = client.newBuilder()// Copy to customize OkHttp for this request.
.readTimeout(500, TimeUnit.MILLISECONDS)
.build();
Request request = new Request.Builder()
.url("http://httpbin.org/delay/1") // This URL is served with a 1 second delay.
.build();
Response response = copyClient.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println("【响应结果】" + response.body().string());
}
Handling authentication 处理身份验证
//处理身份验证
public void handlingAuthentication() throws Exception {
client = new OkHttpClient.Builder()
.authenticator((route, response) -> {//身份验证
System.out.println("【Authenticating for response】" + response);
System.out.println("【Challenges】" + response.challenges());//获取认证质疑的方案和领域
return response.request()
.newBuilder()
.header("Authorization", Credentials.basic("jesse", "password1"))//对请求头进行编码
.build();
})
.build();
Request request = new Request.Builder()
.url("http://publicobject.com/secrets/hellosecret.txt")
.build();
}
if (credential.equals(response.request().header("Authorization"))) return null; // If we already failed with these credentials, don't retry.
当你超过应用程序定义的尝试连接限制(次数)时,你也可能希望跳过重试:
if (responseCount(response) >= 3) return null; // If we've failed 3 times, give up.
private int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
附件列表
OkHttp 官方Wiki之【使用案例】的更多相关文章
- OkHttp 官方Wiki【设计思想】
官方Wiki之Calls 原文位置:https://github.com/square/okhttp/wiki/Calls The HTTP client's job is to accept you ...
- Flume性能测试报告(翻译Flume官方wiki报告)
因使用flume的时候总是会对其性能有所调研,网上找的要么就是自测的这里找到一份官方wiki的测试报告供大家参考 https://cwiki.apache.org/confluence/display ...
- OkHttp使用进阶(译自OkHttp官方教程)
没有使用过OkHttp的,可以先看OkHttp使用介绍 英文版原版地址 Recipes · square/okhttp Wiki 同步get 下载一个文件,打印他的响应头,以string形式打印响应体 ...
- Ubuntu官方Wiki教程资源
前言:通常学习一样新知识时,最快的方式是通过搜索引擎然后以最快的方式拿枪上战场,如果接下来还一直依赖搜索引擎去打,那么你会发现自己永远都在打游击:那么如果要解决这个问题,必须要学会系统的学习,只有连贯 ...
- iosOpenDev-install 失败官方wiki无法解决看这里(尝试有效)
https://github.com/kokoabim/iOSOpenDev/wiki/Troubleshoot http://blog.csdn.net/bluesky_03/article/det ...
- SOA_Oracle SOA Suite and BPM Suite 11g官方虚拟机安装指南(案例)
参考:Oracle官方 - http://www.oracle.com/technetwork/middleware/soasuite/learnmore/vmsoa-172279.html?ssSo ...
- .Net轻量级ORM-NPoco的使用方法-摘自NPoco国外官方Wiki
文章引用自NPoco官方Wiki,地址:https://github.com/schotime/NPoco/wiki,因公司网络不稳定,有时无法访问,特将其摘抄. Home Adam Schroder ...
- OkHttp官方中文文档
https://blog.csdn.net/jackingzheng/article/details/51778793 https://www.cnblogs.com/ldq2016/p/879630 ...
- Android okHttp网络请求之Get/Post请求
前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...
随机推荐
- 【知了堂学习笔记】java 底层容易忽略的知识点
1. java中的关键字 提到关键字,最主要的就是不能用关键字作为标识符,值得注意的有以下几点. ①其中goto与const在java中没有定义,但是也是关键字.这个基本用不到,但是应该有个认知. ② ...
- MIT-6.828-JOS-环境搭建
MIT 6.828是操作系统中最经典的一门课程.完成所有的lab就相当于完成了一个迷你的操作系统.我跟的是2018年的课程,课程首页在6.828课程官网.当然所有资料都是英文的,所以难度也不低,这里推 ...
- Maven项目使用阿里云的Maven库
Maven项目下载一些jar包非常慢,有时候一个项目能下一个上午,因此可以考虑使用阿里云的Maven库,因为是国内的,所以下载速度非常酷 单个项目使用阿里云的Maven库: pom文件中 <!- ...
- Java工具类- 跨域工具类
原本Spring MVC项目添加跨域: 在web.xml文件中配置: <!-- cors解决跨域访问问题 --> <filter> <filter-name>cor ...
- Java double 精度
1. 范围 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) ...
- MongoDB复制原理
##mongodb复制(主从服务器数据备份, 一个主服务器可以有很多个从服务器) #mongodb的复制至少需要两个节点.其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据 ...
- JavaSE基础之JDBC
JavaSE基础之JDBC 1.JDBC 的步骤: ①加载数据库驱动: a.MySQL:com.mysql.jdbc.Driver: b.SQLServer:com.microsoft.jdbc.sq ...
- bzoj 1006: [HNOI2008]神奇的国度 -- 弦图(最大势算法)
1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec Memory Limit: 162 MB Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角 ...
- python循环与判断
学习一门新的语言最重要的就是练习. 一.脚本需求: 编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定 二.脚本流程图: 写代码之前画个流程图总是好的,可以让你理清思路,避免写着写着 ...
- C#高级编程9-第3章 对象与类型
类与结构 类和结构都是对象的模板 类定义了处理和访问数据的方法,通过类的实例化进行逻辑处理 类与结构的区别是类是引用类型,存储在托管堆上:结构是值类型,存储在栈上的: 类使用class进行修饰,结构使 ...