作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在连接到 webService
,如下所示:
private CompositeDisposable mCompositeDisposable;
PublicApi publicApi = retrofitApi.getClient("https://xxx.xxx.xxx", context, 1);
mCompositeDisposable.add(publicApi.language("getLanguages")
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(language -> responseLanguage(language, resultListener), language -> errorLanguage(language, resultListener)));
得到如下结果:
private void responseLanguage(Languages languages, RemoteDataSource.ResultListener<Languages> resultListener) {
}
private void errorLanguage(Throwable error, RemoteDataSource.ResultListener<Languages> resultListener) {
error.printStackTrace();
}
我怎样才能像下面的链接一样检查响应来源:
Retrofit 2 — Check Response Origin (Network, Cache, or Both)
我需要知道结果是来自缓存还是网络服务(在线),因为我正在缓存结果,如下所示:
public class RetrofitApi {
private static PublicApi retrofit = null;
private Context context;
public PublicApi getClient(String url, Context context, Integer value) {
OkHttpClient okHttpClient;
this.context = context;
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
if (value == 1) {
//For get Log see D/OkHttp
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
File httpCacheDirectory = new File(this.context.getCacheDir(), "responses");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
okHttpClient = builder.
addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(OFFLINE_INTERCEPTOR)
.addInterceptor(logging)
.cache(cache)
.build();
} else {
okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(OFFLINE_INTERCEPTOR)
.addInterceptor(logging)
.cache(cache)
.build();
}
} else {
okHttpClient = builder.build();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(okHttpClient)
//.client(httpClient.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PublicApi.class);
return retrofit;
}
private Interceptor REWRITE_RESPONSE_INTERCEPTOR = chain -> {
Response originalResponse = chain.proceed(chain.request());
String cacheControl = originalResponse.header("Cache-Control");
if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") ||
cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) {
return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + 60)
.build();
} else {
return originalResponse;
}
};
private Interceptor OFFLINE_INTERCEPTOR = chain -> {
Request request = chain.request();
if (!Utils.isNetworkAvailable(context)) {
int maxStale = 60 * 60 * 24 * 2; // tolerate 2-days stale
request = request.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
return chain.proceed(request);
};
}
最佳答案
您可以将预期的对象包装在 PublicApi
处与 Retrofit 的接口(interface) Response
对象,将 RxJava 与 RxJavaCallAdapaterFactory
一起使用时:
@GET
Response<Languages> language(String param);
Response
是包含有关响应的各种信息的请求响应的包装器,这与您提到的 article 中的对象相同,即在非 RxJava 中返回 enqueue()
使用时请求 Call<>
.
然后在订阅者中你会得到一个 Response<Languages>
对象,您将能够使用 response.raw().cacheResponse()
检查它是否是缓存对象/response.raw().networkResponse()
如上述教程中所述。
关于android - Retrofit 2 + rx - 如何在 android 中检查响应来源(网络、缓存或两者)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45387848/
我是一名优秀的程序员,十分优秀!