2016-05-19 45 views
5

Sto provando ad elaborare una risposta del server che è GZIP'd. La risposta viene fornito con un colpo di testaRetrofit: come analizzare la risposta di GZIP senza codifica del contenuto: gzip header

Content-Type: application/x-gzip 

ma non ha intestazione

Content-Encoding: gzip 

Se aggiungo che intestazione utilizzando un proxy, la risposta viene analizzato bene. Non ho alcun controllo sul server, quindi non posso aggiungere l'intestazione.

Posso forzare Retrofit per trattarlo come contenuto GZIP? C'è un modo migliore? L'URL per il server è: http://crowdtorch.cms.s3.amazonaws.com/4474/Updates/update-1.xml

risposta

1

C'è un modo migliore di reinventare la ruota. Basta aggiungere tu stesso l'intestazione 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(); 
}) 

Infatti, il codice è un classico esempio dei mali del utilizzando il codice interno (come com.sun pacchetti dal JDK). RealResponseBody non ha più quel costruttore.

+0

Interessante. Usa un intercettore. Buona idea. Sembra che dovrebbe funzionare. – itsymbal

+0

@itsymbal lo fa, lo uso –

6

L'ho capito. L'idea è di aggiungere un interceptor personalizzato che prenderà la risposta non ancora decompressa e decomprimerla 'manualmente' - fare la stessa cosa che OkHttp farebbe automaticamente in base all'intestazione Content-Encoding, ma senza richiedere quell'intestazione.

è come DIS:

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

E l'Interceptor è come DIS:

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

e la funzione di decompressione è come 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(); 
} 
Problemi correlati