我使用 POST 请求访问服务器并且在从服务器获取数据时不要向服务器发送数据。
@POST("Index/getListShopsInfo")
Observable<ShopList> getListShopsInfo();
我想为我的数据添加一个本地缓存。
public class CacheInterceptor implements Interceptor {
private Context mContext;
public CacheInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
boolean netAvailable = AppUtils.isNetworkAvailable(mContext);
if (netAvailable) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_NETWORK)
.build();
} else {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (netAvailable) {
response = response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + 60 * 60)
.build();
} else {
response = response.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached, max-stale=" + 7 * 24 * 60 * 60)
.build();
}
return response;
}
}
File cacheFile = new File(AppUtils.getDiskCacheDir(getContext()), "responses");
Cache cache = new Cache(cacheFile, App.DEFAULT_DIR_CACHE);
OkHttpClient client = new OkHttpClient().newBuilder()
.addInterceptor(new CacheInterceptor(getContext()))
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.cache(cache)
.build();`
mRetrofit = new Retrofit.Builder()
.baseUrl(App.LOGINURL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
当网络连接时,我可以访问服务器,但是当网络不连接时,我的帖子将被拦截。它会记录错误:
HTTP 504 Unsatisfiable Request (only-if-cached)
我检查了本地缓存路径,确实有我建的“responses”文件夹,里面有一个名为“journal”的文件。当我以文本格式打开它时,它是这样的:
我不知道怎么解决。
希望有人能帮助我!
最佳答案
我搜索了几天,找到了解决方案。
首先,将 POST 请求更改为 GET。
@GET("Index/getListShopsInfo")
Call<ShopList> getListShopsInfo();
其次。更改拦截器。
private final Interceptor REWRITE_RESPONSE_INTERCEPTOR = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.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=" + 5000)
.build();
} else {
return originalResponse;
}
}
};
private final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!AppUtils.isNetworkAvailable(getContext())) {
request = request.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, only-if-cached")
.build();
}
return chain.proceed(request);
}
};
第三.okhttpClient.
File cacheFile = new File(AppUtils.getDiskCacheDir(getContext()), "FuckYouSecondDad");
Cache cache = new Cache(cacheFile, App.DEFAULT_DIR_CACHE);
OkHttpClient client = new OkHttpClient().newBuilder()
.cache(cache)
.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
.build();
FORTH.改造。
mRetrofit = new Retrofit.Builder()
.baseUrl(App.LOGINURL)
.client(mClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
现在当互联网连接时,我得到了缓存。它是这样的:
最重要的是,不要忘记添加:
.removeHeader("Pragma")
不然又会报错504
关于android - Retrofit+Okhttp.HTTP 504 Unsatisfiable Request (only-if-cached),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42927216/