首先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:服務器