2017-04-26 71 views
0

我正在開發一個應用程序,使用Retrofit 2向API請求。這個API是ASP.NET,它是用gzip和編碼壓縮和解爲Base64,如下面的代碼:修改響應主體改造2.2攔截器

private static string Compress(string conteudo) 
{ 
    Encoding encoding = Encoding.UTF8; 
    byte[] raw = encoding.GetBytes(conteudo); 

    using (var memory = new MemoryStream()) 
    { 
     using (GZipStream gzip = new GZipStream(memory, CompressionMode.Compress, true)) 
     { 
      gzip.Write(raw, 0, raw.Length); 
     } 
     return Convert.ToBase64String(memory.ToArray()); 
    } 
} 

private static string Decompress(string conteudo) 
{ 
    Encoding encoding = Encoding.UTF8; 
    var gzip = Convert.FromBase64String(conteudo); 

    using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress)) 
    { 
     int size = gzip.Length; 
     byte[] buffer = new byte[size]; 
     using (MemoryStream memory = new MemoryStream()) 
     { 
      int count = 0; 
      do 
      { 
       count = stream.Read(buffer, 0, size); 
       if (count > 0) 
       { 
        memory.Write(buffer, 0, count); 
       } 
      } 
      while (count > 0); 
      return encoding.GetString(memory.ToArray()); 
     } 
    } 
} 

現在,我需要在我的Android應用程序做的就是從改造的響應,從解碼Base64並解壓縮。我試圖用Interceptor來做,但我沒有成功。

這是我從服務H4sIAAAAAAAEACspKk0FAI1M/P0EAAAA收到的回覆,解碼和解壓縮回復,我們有true

是否有人知道該怎麼辦呢?

回答

2

這很容易。下面的代碼使用Google Guava來解碼Base64字符流和Google Gson以反序列化JSON內容。

請看下面的測試服務接口:

abstract class AbstractTransformingDecodingInterceptor 
     implements Interceptor { 

    protected abstract InputStream transformInputStream(InputStream inputStream) 
      throws IOException; 

    @Override 
    @SuppressWarnings("resource") 
    public final Response intercept(final Chain chain) 
      throws IOException { 
     final Request request = chain.request(); 
     final Response response = chain.proceed(request); 
     final ResponseBody body = response.body(); 
     return response.newBuilder() 
       .body(ResponseBody.create(
         body.contentType(), 
         body.contentLength(), 
         Okio.buffer(Okio.source(transformInputStream(body.byteStream()))) 
       )) 
       .build(); 
    } 

} 

此實現也應該檢測內容MIME:

interface IService { 

    @GET("/") 
    Call<String> get(); 

} 

現在你可以使用模板方法設計模式,實現你的攔截器響應輸入流變壓器基地類型爲了不做錯誤的轉換,但你可以輕鬆地實現它。因此,這裏也是兩個Base64編碼和gzip兩個轉換攔截:

final class Base64DecodingInterceptor 
     extends AbstractTransformingDecodingInterceptor { 

    private static final Interceptor base64DecodingInterceptor = new Base64DecodingInterceptor(); 

    private Base64DecodingInterceptor() { 
    } 

    static Interceptor getBase64DecodingInterceptor() { 
     return base64DecodingInterceptor; 
    } 

    @Override 
    protected InputStream transformInputStream(final InputStream inputStream) { 
     return BaseEncoding.base64().decodingStream(new InputStreamReader(inputStream)); 
    } 

} 
final class GzipDecodingInterceptor 
     extends AbstractTransformingDecodingInterceptor { 

    private static final Interceptor gzipDecodingInterceptor = new GzipDecodingInterceptor(); 

    private GzipDecodingInterceptor() { 
    } 

    static Interceptor getGzipDecodingInterceptor() { 
     return gzipDecodingInterceptor; 
    } 

    @Override 
    protected InputStream transformInputStream(final InputStream inputStream) 
      throws IOException { 
     return new GZIPInputStream(inputStream); 
    } 

} 

並對其進行測試:

private static final OkHttpClient okHttpClient = new OkHttpClient.Builder() 
     .addInterceptor(getGzipDecodingInterceptor()) 
     .addInterceptor(getBase64DecodingInterceptor()) 
     .addInterceptor(getFakeContentInterceptor()) 
     .build(); 

private static final Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl("http://whatever") 
     .client(okHttpClient) 
     .addConverterFactory(GsonConverterFactory.create()) 
     .build(); 

private static final IService service = retrofit.create(IService.class); 

public static void main(final String... args) 
     throws IOException { 
    final String body = service.get().execute().body(); 
    System.out.println(body); 
} 

注意getFakeContentInterceptor返回假的攔截器,它總是返回H4sIAAAAAAAEACspKk0FAI1M/P0EAAAA,使baseUrl不甚至有一個真正的URL。輸出:

真正

+0

再次,你幫了我很多,非常感謝你:再次d – jackcar

+0

@jackcar,真的嗎?哈,不客氣! :) –