Android - OKHttp:如何为POST启用gzip

Tob*_*ich 2 android gzip nginx retrofit okhttp

在我们的Android应用程序中,我正在向我们的(NGINX)服务器发送相当大的文件,所以我希望使用gzip作为我的Retrofit POST消息.

有许多关于OkHttp的文档透明地使用gzip或更改头文件以接受gzip(即在GET消息中).

但是如何启用此功能以从我的设备发送gzip http POST消息?我是否必须写一个自定义的Intercepter或其他东西?或者只是在标题中添加一些东西?

小智 6

根据以下配方:gzip的正确流程将是这样的:

OkHttpClient client = new OkHttpClient.Builder()
      .addInterceptor(new GzipRequestInterceptor())
      .build();

/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
  static 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; // We don't know the compressed length in advance!
        }

        @Override public void writeTo(BufferedSink sink) throws IOException {
          BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
          body.writeTo(gzipSink);
          gzipSink.close();
        }
      };
    }
  }
Run Code Online (Sandbox Code Playgroud)