这很容易。下面的代码使用 Google Guava 来解码 Base64 字符流,并使用 Google Gson 来反序列化 JSON 内容。
考虑以下测试服务接口:
interface IService {
@GET("/")
Call<String> get();
}
现在您可以使用模板方法设计模式来实现拦截器响应输入流转换器基础:
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 类型,以免进行错误的转换,但您可以轻松地自己实现。因此,这里还有两个适用于 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。输出:
true