OKHttp支持以下功能:

  1. http/2支持,同一个host可以共享一个端口
  2. 如果http/2不支持,则使用连接池降低请求延迟
  3. 透明gzip请求的返回
  4. 可以针对重复的网络请求进行缓存

下文将分几个方向介绍OKHttp:

1.引用

当前最新版本是3.9.1,使用maven仓库引入即可,maven配置如下:

1
2
3
4
5
	<dependency>
	    <groupId>com.squareup.okhttp3</groupId>
	    <artifactId>okhttp</artifactId>
	    <version>3.9.1</version>
	</dependency>

gradle 配置如下:

1
compile 'com.squareup.okhttp3:okhttp:3.9.1'

2.先引入一个函数来表示具体的请求,后边的执行大多会使用这个函数来发起具体的请求

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
private static Response executeRequest(final OkHttpClient okHttpClient, final Request build) {
        try {
            final Response response = okHttpClient.newCall(build).execute();
            if (response.isSuccessful()) {
                System.out.println(response.code() + " : " + response.body().string().length());
            } else {
                System.out.println(response.code());
            }
            return response;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

3.基本的get请求

1
2
3
4
5
6
final Request build = new Request.Builder().url("http://blog.shrp.me")
                .header("PostId", "12345")
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("simple get: ");
        executeRequest(okHttpClient, build);

4.基本的post请求

1
2
3
4
5
6
7
8
9
final MediaType parse = MediaType.parse("application/json");
        final RequestBody requestBody = RequestBody.create(parse, "{}");
        final Request build = new Request.Builder().url("http://blog.shrp.me")
                .post(requestBody)
                .header("PostId", "12345")
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("simple post: ");
        executeRequest(okHttpClient, build);

5.multipart post请求

1
2
3
4
5
6
7
8
9
final MultipartBody form = new MultipartBody.Builder().addFormDataPart(
                "test", "test"
        ).build();
        final Request build = new Request.Builder().url("http://blog.shrp.me")
                .post(form)
                .header("PostId", "12345")
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("multipart post: ");

6.带有缓存功能的get

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
final File cacheDir = Files.createTempDirectory("test").toFile();
        final Cache cache = new Cache(cacheDir, MAX_SIZE);
        final OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(cache).build();
        final Request build = new Request.Builder().url("http://blog.shrp.me")
                .header("PostId", "12345")
                .cacheControl(CacheControl.FORCE_NETWORK)
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("cached get: ");
        final Response response = executeRequest(okHttpClient, build);
        assert response.networkResponse() != null;
        final Request request2 = new Request.Builder().url("http://blog.shrp.me")
                .header("PostId", "12345")
                .cacheControl(CacheControl.FORCE_CACHE)
                .addHeader("client-version", "3.9.1")
                .build();
        final Response response2 = executeRequest(okHttpClient, request2);
        assert response2.cacheResponse() != null;

7.异步请求

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
final Request build = new Request.Builder().url("http://blog.shrp.me")
                .header("PostId", "12345")
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("async get: ");
        okHttpClient.newCall(build).enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                System.out.println(call.request().url() + " is failed. " + e.getMessage());
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                if (response.isSuccessful()) {
                    System.out.println(response.code() + " : " + response.body().string().length());
                } else {
                    System.out.println(response.code());
                }
            }
        });

8.带有拦截器的请求

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 final File cacheDir = Files.createTempDirectory("test").toFile();
        final Cache cache = new Cache(cacheDir, MAX_SIZE);
        final OkHttpClient okHttpClient = new OkHttpClient.Builder().cache(cache)
                .addInterceptor(chain -> {
//                    System.out.println("intercept 1.");
                    final Response proceed = chain.proceed(chain.request());
                    System.out.println("intercept 1 return.");
                    return proceed;
                })
                .addInterceptor(chain -> {
                    System.out.println("intercept 2.");
                    final Response proceed = chain.proceed(chain.request());
                    System.out.println("intercept 2 return.");
                    return proceed;
                })
                .addNetworkInterceptor(chain -> {
                    System.out.println("network intercept.");
                    final Response proceed = chain.proceed(chain.request());
                    System.out.println("network intercept return.");
                    return proceed;
                })
                .build();
        final Request build = new Request.Builder().url("http://blog.shrp.me")
                .header("PostId", "12345")
                .addHeader("client-version", "3.9.1")
                .build();
        System.out.print("intercept get: ");
        executeRequest(okHttpClient, build);
        System.out.print("intercept get from cache: ");
        executeRequest(okHttpClient, build);

9.还可以添加认证器,在异步调用后使用cancel取消等功能。

okhttp的api更易用,据说性能也不错。以后有机会可以进行性能的比较。本文代码可以在https://github.com/stirp/MyTests找到。