OkHttp 3.4入门

配置方法

(一)导入Jar包
http://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/3.4.0-RC1/okhttp-3.4.0-RC1.jar

(二)Gradle

compile 'com.squareup.okhttp3:okhttp:3.4.0-RC1'

使用方法
HTTP GET
private void get_String(){
    Request request = new Request.Builder()
            .url("http://publicobject.com/helloworld.txt")
            .build();
    new OkHttpClient().newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
        @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());
        }
    });
}

HTTP POST

POST json数据 
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {    RequestBody body = RequestBody.create(JSON, json);    Request request = new Request.Builder()      .url(url)      .post(body)      .build();    Response response = client.newCall(request).execute();    f (response.isSuccessful()) {        return response.body().string();    } else {        throw new IOException("Unexpected code " + response);    }}

POST提交键值对 
OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {    RequestBody formBody = new FormEncodingBuilder()
    //.add("platform", "android")    //.add("name", "bug")    //.add("subject", "XXXXXXXXXXXXXXX")
     .add("search", "Jurassic Park")

.build();     Request request = new Request.Builder()      .url("https://en.wikipedia.org/w/index.php")      .post(formBody)      .build();     Response response = client.newCall(request).execute();    if (response.isSuccessful()) {        return response.body().string();    } else {        throw new IOException("Unexpected code " + response);    }}

Headers(提取响应头)

Request request = new Request.Builder()
        .url("https://api.github.com/repos/square/okhttp/issues")
        .header("User-Agent", "OkHttp Headers.java")
        .addHeader("Accept", "application/json; q=0.5")
        .addHeader("Accept", "application/vnd.github.v3+json")

.addHeader("Cookie", "cookie")
        .build();
try {
    Response response = mClient.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
   /* System.out.println("Server: " + response.header("Server"));
    System.out.println("Date: " + response.header("Date"));
    System.out.println("Vary: " + response.headers("Vary"));*/
    Log.i("WY", "数据:" + response.toString());
} catch (IOException e) {
    e.printStackTrace();
}

Get请求Gson数据

static class Gist {
    Map<String, GistFile> files;
}
static class GistFile {
    String content;
}
public void run_JSON() throws Exception {
    Request request = new Request.Builder()
            .url("https://api.github.com/gists/c2a7c39532239ff261be")
            .build();
    new OkHttpClient().newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            Gist gist = gson.fromJson(response.body().charStream(), Gist.class);
            for (Map.Entry<String, GistFile> entry : gist.files.entrySet()) {
                System.out.println("111 "+entry.getKey());
                System.out.println(entry.getValue().content);
            }
        }
    });
}

独立请求设置
由于在一个程序中只能声明一个OkHttpClient实例,如果要更改连接超时时间,或者其他参数可使用newBuilder进行设置。
public class PreRequestClass {
    private final OkHttpClient client = new OkHttpClient();
    public void run() throws Exception {
        Request request = new Request.Builder()
                .url("http://httpbin.org/delay/1") // This URL is served with a 1 second delay.
                .build();
        // Copy to customize OkHttp for this request.
        OkHttpClient copy = client.newBuilder()
                .readTimeout(5000, TimeUnit.MILLISECONDS)
                .build();
        copy.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println("Response 1 succeeded: " + response);
            }
        });
        OkHttpClient copy2 = client.newBuilder()
                .readTimeout(3000, TimeUnit.MILLISECONDS)
                .build();
        copy2.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println("Response 2 succeeded: " + response);
            }
        });
    }
}

(Post方式提交String)

使用HTTP POST提交请求到服务。这个例子提交了一个markdown文档到web服务,以HTML方式渲染markdown。因为整个请求体都在内存中,因此避免使用此api提交大文档(大于1MB)。

public static final MediaType MEDIA_TYPE_MARKDOWN      = MediaType.parse("text/x-markdown; charset=utf-8");

private final OkHttpClient client = new OkHttpClient();

public void run() 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))

.build();

Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());

}

Post Streaming(Post方式提交流)

以流的方式POST提交请求体。请求体的内容由流写入产生。这个例子是流直接写入Okio的BufferedSink。你的程序可能会使用OutputStream,你可以使用BufferedSink.outputStream()来获取。.

public static final MediaType MEDIA_TYPE_MARKDOWN      = MediaType.parse("text/x-markdown; charset=utf-8");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {

RequestBody requestBody = new RequestBody() {

@Override public MediaType contentType() {

return MEDIA_TYPE_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)

.build();

Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());

}

Posting a File(Post方式提交文件)

以文件作为请求体是十分简单的。

public static final MediaType MEDIA_TYPE_MARKDOWN      = MediaType.parse("text/x-markdown; charset=utf-8");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {

File file = new File("README.md");

Request request = new Request.Builder()

.url("https://api.github.com/markdown/raw")

.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))

.build();

Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());

}

Posting a multipart request(Post方式提交分块请求)

MultipartBuilder可以构建复杂的请求体,与HTML文件上传形式兼容。多块请求体中每块请求都是一个请求体,可以定义自己的请求 头。这些请求头可以用来描述这块请求,例如他的Content-Disposition。如果Content-Length和Content-Type可 用的话,他们会被自动添加到请求头中。

private static final String IMGUR_CLIENT_ID = "...";

private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

private final OkHttpClient client = new OkHttpClient();

public void run() throws Exception {    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image

RequestBody requestBody = new MultipartBody.Builder()

.setType(MultipartBody.FORM)

.addFormDataPart("title", "Square Logo")

.addFormDataPart("image", "logo-square.png",  RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))

.build();

Request request = new Request.Builder()

.header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)

.url("https://api.imgur.com/3/image")

.post(requestBody)

.build();

Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());

}

Response Caching(响应缓存)

为了缓存响应,你需要一个你可以读写的缓存目录,和缓存大小的限制。这个缓存目录应该是私有的,不信任的程序应不能读取缓存内容。
一个缓存目录同时拥有多个缓存访问是错误的。大多数程序只需要调用一次new OkHttp(),在第一次调用时配置好缓存,然后其他地方只需要调用这个实例就可以了。否则两个缓存示例互相干扰,破坏响应缓存,而且有可能会导致程序崩溃。
响应缓存使用HTTP头作为配置。你可以在请求头中添加Cache-Control: max-stale=3600 ,OkHttp缓存会支持。你的服务通过响应头确定响应缓存多长时间,例如使用Cache-Control: max-age=9600。

private final OkHttpClient client;

public CacheResponse(File cacheDirectory) throws Exception {

int cacheSize = 10 * 1024 * 1024; // 10 MiB

Cache cache = new Cache(cacheDirectory, cacheSize);

client = new OkHttpClient.Builder()

.cache(cache)

.build();

}

public void run() throws Exception {

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("Response 2 equals Response 1? " + response1Body.equals(response2Body));

}

为了防止使用缓存的响应,可以用CacheControl.FORCE_NETWORK。为了防止它使用网络,使用 CacheControl.FORCE_CACHE。需要注意的是:如果您使用FORCE_CACHE和网络的响应需求,OkHttp则会返回一个504 提示,告诉你不可满足请求响应。

Handling authentication(处理验证)

OkHttp会自动重试未验证的请求。当响应是401 Not Authorized时,Authenticator会被要求提供证书。Authenticator的实现中需要建立一个新的包含证书的请求。如果没有证书可用,返回null来跳过尝试。

private final OkHttpClient client;

public Authenticate() {

client = new OkHttpClient.Builder()

.authenticator(new Authenticator() {

@Override

public Request authenticate(Route route, Response response) throws IOException {

System.out.println("Authenticating for response: " + response);

System.out.println("Challenges: " + response.challenges());

String credential = Credentials.basic("jesse", "password1");

return response.request().newBuilder()

.header("Authorization", credential)

.build();

}

}).build();

}

public void run() throws Exception {

Request request = new Request.Builder()

.url("http://publicobject.com/secrets/hellosecret.txt")

.build();

Response response = client.newCall(request).execute();

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

System.out.println(response.body().string());

}

不用header添加参数,formbody添加方法:

可以遍历formBody,循环添加 formBody

最好的办法是重写 FormBody,追加添加参数的方法。

private void intercep() {

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
//请求定制:添加请求
Request.Builder requestBuilder = original.newBuilder()
.header("APIKEY", "API_KEY");
//请求体定制:统一添加token参数
if (original.body() instanceof FormBody) {
FormBody.Builder newFormBody = new FormBody.Builder();
FormBody oidFormBody = (FormBody) original.body();
for (int i = 0; i < oidFormBody.size(); i++) {
newFormBody.addEncoded(oidFormBody.encodedName(i), oidFormBody.encodedValue(i));
}
newFormBody.add("token", "API_TOKEN");
requestBuilder.method(original.method(), newFormBody.build());
}
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}

OkHttp官方文档:https://github.com/square/okhttp/wiki

源码下载

OkHttp 3.4入门的更多相关文章

  1. OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据

    OkHttp框架从入门到放弃,解析图片使用Picasso裁剪,二次封装OkHttpUtils,Post提交表单数据 我们这片博文就来聊聊这个反响很不错的OkHttp了,标题是我恶搞的,本篇将着重详细的 ...

  2. 毕加索的艺术——Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选

    毕加索的艺术--Picasso,一个强大的Android图片下载缓存库,OkHttpUtils的使用,二次封装PicassoUtils实现微信精选 官网: http://square.github.i ...

  3. OkHttp 入门篇

    OkHttp是一个HTTP & HTTP2的客户端,能够用来进行Android 和 Java 开发. HTTP是现代应用的最基本的网络环境.让你的HTTP更加有效的工作能够让你的东西加载更快而 ...

  4. 「2020 新手必备 」极速入门 Retrofit + OkHttp 网络框架到实战,这一篇就够了!

    老生常谈 什么是 Retrofit ? Retrofit 早已不是什么新技术了,想必看到这篇博客的大家都早已熟知,这里就不啰嗦了,简单介绍下: Retrofit 是一个针对 Java 和 Androi ...

  5. 简单的OkHttp使用介绍

    Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient.关于HttpURLConnection和HttpClient的选择>>官方博客尽管Go ...

  6. OkHttp使用教程

    Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient.关于HttpURLConnection和HttpClient的选择>>官方博客尽管Go ...

  7. Okio 1.9简单入门

    Okio 1.9简单入门 Okio库是由square公司开发的,补充了java.io和java.nio的不足,更加方便,快速的访问.存储和处理你的数据.而OkHttp的底层也使用该库作为支持. 该库极 ...

  8. 关于okhttp

    本文出处:http://www.tuicool.com/articles/rArq63u 为什么需要一个HTTP库 Android系统提供了两种HTTP通信类,HttpURLConnection和Ht ...

  9. OkHttp使用介绍

    版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/4001708.html 为什么需要一个HTTP库 Androi ...

随机推荐

  1. html5新增及删除标签

    一.新增标签 有一种划分为,功能性标签[html5新增,如canvas,旧浏览器没有]和语义性标签[如header等只是增强语义,没有新功能].下面按照分几个小类来说. 1.结构标签 新增的结构标签, ...

  2. Caffe 抽取CNN网络特征 Python

    Caffe Python特征抽取 转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ Caffe大家一般用到的深度学 ...

  3. selenium结合sikuliX操作Flash网页

    sikuli的官网地址:http://www.sikuli.org 首先下载sikuliX的jar包:https://launchpad.net/sikuli/sikulix/1.1.0 java-d ...

  4. 代码覆盖率工具 EMMA

    使用 EMMA 获得功能测试覆盖率 测试覆盖率是评价测试完整性的重要的度量标准之一. EMMA 是一个面向 Java 代码的测试覆盖率收集工具.在测试过程中,使用 EMMA 能使收集和报告测试覆盖率的 ...

  5. 嵌入式Linux驱动学习之路(三)u-boot配置分析

    u-boot配置流程分析 执行make tiny4412_config后,将会对u-boot进行一些列的配置,以便于后面的编译. 打开顶层目录下的Makefile,查找对于的规则tiny4412_co ...

  6. hibernate考试题

    1.在Hibernate中,以下关于主键生成器说法错误的是(C). A.increment可以用于类型为long.short或byte的主键 long,short,byte都是特殊的int类型 B.i ...

  7. [No000008]发工资不仅仅是让你写代码的

    这是我对团队每个新进员工说的第一件事情.这句话的意思是,我并不关心你是如何快速完成任务的,哪怕代码很差,只要它像救生艇通气门一样管用就行.这句话也是我最喜欢的座右铭之一. 这个说法其实很合理:我们的工 ...

  8. Hibernate 和快照

    8.Oracle中的数据类型 9.Oracle中的伪列 Rowid和RowNum Rowid Rownum:在内存中形成一个不断裂的自增列 --最重要的.就是Oracle分页 我想要emp中的第二页数 ...

  9. 2055 [ZJOI2009]假期的宿舍

    P2055 [ZJOI2009]假期的宿舍 题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题.比如 A 和 B 都是学校的学生,A ...

  10. Html5 Egret游戏开发 成语大挑战(八)一般性二级页面处理

    在游戏中,我们一般会有各种各样的二级页面,比如游戏暂停界面或者游戏结束界面,这些界面组成了对玩家交互主要手段,在游戏开发中,对于这些界面的coding组织是非常有学问的,如果倒退到十年前,游戏开发的老 ...