改造+ Okhttp.HTTP 504不满意的请求(仅限缓存)

时间:2017-03-21 12:29:56

标签: android retrofit2 okhttp3

我使用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不满意请求(仅限缓存)

我检查了本地缓存路径,它确实有&#34;响应&#34;我建立的文件夹,有一个名为&#34; journal&#34;在它。当我以文本格式打开它时,它是这样的:

enter image description here

而且我不知道如何解决它。

希望有人能帮助我!

1 个答案:

答案 0 :(得分:10)

我搜索了几天,然后找到了解决方案。

FIRST。将POST请求更改为GET。

@GET("Index/getListShopsInfo") Call<ShopList> getListShopsInfo();

SECOND.Change the Inteceptor。

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);
    }
};

THIRD.the 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.the retrofit。

mRetrofit = new Retrofit.Builder()
            .baseUrl(App.LOGINURL)
            .client(mClient)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

现在连接互联网时,我得到了缓存。就像这样:

enter image description here

最重要的是,不要忘记添加:

.removeHeader("Pragma")

或者你会再次弄错504.