2016-05-19 21 views
5

GZIPされたサーバーレスポンスを処理しようとしています。レスポンスヘッダRetrofit:コンテンツエンコーディングなしでGZIPの応答を解析する方法:gzip header

Content-Type: application/x-gzip 

が付属していますが、私はプロキシを使用して、そのヘッダを追加する場合は、ヘッダ

Content-Encoding: gzip 

を持っていない、応答がうまく解析されます。 私はサーバーを制御していないので、ヘッダーを追加することはできません。

Retrofitで強制的にGZIPコンテンツとして扱うことはできますか?より良い方法がありますか? サーバーのURL: http://crowdtorch.cms.s3.amazonaws.com/4474/Updates/update-1.xml

答えて

1

より良い方法があります車輪の再発明。 Content-Encodingヘッダーを自分で追加するだけです。実際に

.addNetworkInterceptor((Interceptor.Chain chain) -> { 
    Request req = chain.request(); 
    Headers.Builder headersBuilder = req.headers().newBuilder(); 

    String credential = Credentials.basic(...); 
    headersBuilder.set("Authorization", credential); 

    Response res = chain.proceed(req.newBuilder().headers(headersBuilder.build()).build()); 

    return res.newBuilder() 
     .header("Content-Encoding", "gzip") 
     .header("Content-Type", ""application/json") 
     .build(); 
}) 

、あなたのコードは、(JDKからcom.sunパッケージのように)内部のコードを使用しての悪の典型的な例です。 RealResponseBodyにはそのコンストラクタがもうありません。

+0

興味深い。インターセプタを使用します。良いアイデア。それはうまくいくはずです。 – itsymbal

+0

@itsymbalです –

6

私はそれを理解しました。そのアイデアは、未だ解凍されていないレスポンスを取るカスタムインターセプターを追加し、それを '手動で解凍する'ことです.OutputHttpがContent-Encodingヘッダーに基づいて自動的に行いますが、ヘッダーは必要ありません。

DISのようなものです:

OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() 
      .addInterceptor(new UnzippingInterceptor()); 
    OkHttpClient client = clientBuilder.build(); 

インターセプタはDISのようなものです:

private class UnzippingInterceptor implements Interceptor { 
    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Response response = chain.proceed(chain.request()); 
     return unzip(response); 
    } 
} 

して解凍機能がDISのようなものです:

// copied from okhttp3.internal.http.HttpEngine (because is private) 
private Response unzip(final Response response) throws IOException { 

    if (response.body() == null) { 
     return response; 
    } 

    GzipSource responseBody = new GzipSource(response.body().source()); 
    Headers strippedHeaders = response.headers().newBuilder() 
      .removeAll("Content-Encoding") 
      .removeAll("Content-Length") 
      .build(); 
    return response.newBuilder() 
      .headers(strippedHeaders) 
      .body(new RealResponseBody(strippedHeaders, Okio.buffer(responseBody))) 
      .build(); 
} 
関連する問題