2016-05-19 30 views
5

Próbuję przetworzyć odpowiedź serwera, która jest GZIP. Odpowiedź przychodzi z nagłówkiemRetrofit: sposób analizowania odpowiedzi GZIP bez kodowania treści: nagłówek gzip

Content-Type: application/x-gzip 

ale nie ma nagłówku

Content-Encoding: gzip 

Jeśli dodam, że nagłówek przy użyciu serwera proxy, odpowiedź zostanie przeanalizowany dobrze. Nie mam żadnej kontroli nad serwerem, więc nie mogę dodać nagłówka.

Czy mogę zmusić Retrofit do traktowania go jako treści GZIP? Czy istnieje lepszy sposób? Adres URL serwera to: http://crowdtorch.cms.s3.amazonaws.com/4474/Updates/update-1.xml

Odpowiedz

1

Istnieje lepszy sposób niż odkrywanie koła. Wystarczy samodzielnie dodać nagłówek 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(); 
}) 

W rzeczywistości, kod jest klasycznym przykładem zła przy użyciu kodu wewnętrznego (jak com.sun pakiety z JDK). RealResponseBody nie ma już tego konstruktora.

+0

Interesujące. Użyj przechwytywacza. Dobry pomysł. Brzmi, jakby to powinno zadziałać. – itsymbal

+0

@ itymbal to robi, ja go używam –

6

Wymyśliłem to. Chodzi o to, aby dodać niestandardowy przechwytywacz, który zajmie nierozpakowaną jeszcze odpowiedź, i rozpakuj go "ręcznie" - wykonaj to samo, co OkHttp wykona automatycznie na podstawie nagłówka Content-Encoding, ale bez potrzeby używania tego nagłówka.

jest jak dis:

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

A Interceptor jest jak dis:

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

a funkcja unzip jest jak 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(); 
} 
Powiązane problemy