Okhttp3請求網絡開啓Gzip壓縮

前沿

首先OkHttp3是支持Gzip解壓縮的,不過咱們要明白,它是支持咱們在發起請求的時候自動加入header,Accept-Encoding: gzip,而咱們的服務器返回的時候header中有Content-Encoding: gzip
關於更多深刻的內容呢,能夠參考閱讀下面這篇文章,講的很是好!
聊聊HTTP gzip壓縮與常見的Android網絡框架html

那麼,咱們在向服務器提交大量數據的時候,但願對post的數據進行gzip壓縮,改怎麼辦?
下邊給出方案!java

方案

官方採用的是自定義攔截器的方式!
源碼在:
okhttp/samples/guide/src/main/java/okhttp3/recipes/RequestBodyCompression.java
廢話很少說,直接上代碼:git

 1 import java.io.IOException;
 2 
 3 import okhttp3.Interceptor;
 4 import okhttp3.MediaType;
 5 import okhttp3.Request;
 6 import okhttp3.RequestBody;
 7 import okhttp3.Response;
 8 import okio.BufferedSink;
 9 import okio.GzipSink;
10 import okio.Okio;
11 
12 public class GzipRequestInterceptor implements Interceptor {
13     @Override
14     public Response intercept(Chain chain) throws IOException {
15         Request originalRequest = chain.request();
16         if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
17             return chain.proceed(originalRequest);
18         }
19 
20         Request compressedRequest = originalRequest.newBuilder()
21                 .header("Content-Encoding", "gzip")
22                 .method(originalRequest.method(), gzip(originalRequest.body()))
23                 .build();
24         return chain.proceed(compressedRequest);
25     }
26 
27     private RequestBody gzip(final RequestBody body) {
28         return new RequestBody() {
29             @Override
30             public MediaType contentType() {
31                 return body.contentType();
32             }
33 
34             @Override
35             public long contentLength() {
36                 return -1; // 沒法提早知道壓縮後的數據大小
37             }
38 
39             @Override
40             public void writeTo(BufferedSink sink) throws IOException {
41                 BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
42                 body.writeTo(gzipSink);
43                 gzipSink.close();
44             }
45         };
46     }
47 }

而後構建OkhttpClient的時候,添加攔截器:github

OkHttpClient okHttpClient = new OkHttpClient.Builder() 
    .addInterceptor(new GzipRequestInterceptor())//開啓Gzip壓縮
    ...
    .build();

後記

若是須要帶有內容長度content-length的,能夠查看這個issue:
Here’s the full gzip interceptor with content length, to whom it may concern:服務器

參考:http://www.javashuo.com/article/p-svjpwahq-bk.html網絡

相關文章
相關標籤/搜索