Okhttp3請求網路開啟Gzip壓縮
阿新 • • 發佈:2019-01-28
前言
首先OkHttp3是支援Gzip解壓縮的,不過我們要明白,它是支援我們在發起請求的時候自動加入header,Accept-Encoding: gzip
,而我們的伺服器返回的時候header中有Content-Encoding: gzip
。
關於更多深入的內容呢,可以參考閱讀下面這篇文章,講的非常好!
聊聊HTTP gzip壓縮與常見的Android網路框架
那麼,我們在向伺服器提交大量資料的時候,希望對post的資料進行gzip壓縮,改怎麼辦?
下邊給出方案!
方案
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;
public class GzipRequestInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
@Override
public MediaType contentType() {
return body.contentType();
}
@Override
public long contentLength() {
return -1; // 無法提前知道壓縮後的資料大小
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}
然後構建OkhttpClient的時候,新增攔截器:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(new GzipRequestInterceptor())//開啟Gzip壓縮
...
.build();