2016-05-19 26 views
5

GZIP'd olan bir sunucu yanıtını işlemeye çalışıyorum. yanıtı, bir başlıkRetrofit: GZIP'd yanıtını Content-Encoding olmadan nasıl ayrıştırılır: gzip header

Content-Type: application/x-gzip 

ile geliyor ama, yanıtı gayet ayrıştırılır alır proxy kullanarak bu başlık eklerseniz başlığını

Content-Encoding: gzip 

yok. Sunucu üzerinde hiçbir kontrolüm yok, bu yüzden üstbilgiyi ekleyemiyorum.

Retrofit'i GZIP içeriği olarak ele almaya zorlayabilir miyim? Daha iyi bir yolu var mı? Sunucu URL'si şudur: http://crowdtorch.cms.s3.amazonaws.com/4474/Updates/update-1.xml

cevap

1

daha iyi bir yolu daha vardır tekerleği yeniden icat etmek. Sadece Content-Encoding başlığını kendiniz ekleyin.

.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(); 
}) 

Aslında, kod dahili kod (gibi JDK com.sun paketleri) kullanmanın kötülüklerin klasik bir örneğidir. RealResponseBody artık bu kurucuya sahip değil.

+0

İlginç. Bir engelleyici kullanın. İyi bir fikir. İşe yaramalı gibi geliyor. – itsymbal

+0

@itsymbal bunu yapar, kullanıyorum –

6

Bunu çözdüm. Buradaki fikir, henüz açılmamış yanıtı alacak özel bir durdurucu eklemektir ve bunu 'el ile' açmaktır - OkHttp'nin İçerik Kodlama üstbilgisine dayanarak otomatik olarak yapacağı aynı şeyi, ancak bu üstbilgiye gerek duymadan yapın.

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

Ve keseni dis gibidir:

dis gibidir dis gibi

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

Ve unzip fonksiyonu geçerli:

// 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(); 
} 
İlgili konular