java – retrofit cache 504不满意的请求(only-if-cached)错误

我一直在测试改造缓存.我正在使用retrofit2.0.0 beta2和okhttp:3.2.0.这是我的代码.

final Cache cache = new Cache(new File(context.getCacheDir(), CACHE_DIR), CACHE_SIZE);
String cachePath = cache.getDirectory().getPath();

OkHttpClient okClient = new OkHttpClient();
okClient.setCache(cache);
okClient.interceptors().add(logging); 

String FORCE_CACHE_HEADERS = "Cache-Control: public, only-if-cached, max-stale=" + Integer.MAX_VALUE;

@GET("/")Call<RES> GETve(@QueryMap Map<String, String> params);
@Headers({FORCE_CACHE_HEADERS})@GET("/")Call<RES> GETCacheve(@QueryMap Map<String, String> params);

第一个请求很好.

###Logging : --> GET https://xxx
###Logging : --> END GET
###OkHttpClient response : Response{protocol=http/1.1, code=200, message=OK, url=https://xxx
###OkHttpClient response.cacheControl() : no-cache, public, max-stale=2419200
###OkHttpClient response.cacheResponse() : null
###Logging : <-- HTTP/1.1 200 OK (133ms)
###Logging : Date: Mon, 11 Apr 2016 06:52:46 GMT
###Logging : Server: Apache/2.2.25 (Unix) mod_ssl/2.2.25 OpenSSL/1.0.0-fips mod_jk/1.2.37
###Logging : Pragma: no-cache
###Logging : Expires: Thu, 01 Jan 1970 00:00:00 GMT
###Logging : Content-Length: 190
###Logging : Keep-Alive: timeout=5, max=100
###Logging : Connection: Keep-Alive
###Logging : Content-Type: text/html;charset=euc-kr
###Logging : Content-Language: euc-kr
###Logging : OkHttp-Sent-Millis: 1460357566280
###Logging : OkHttp-Received-Millis: 1460357566290
###Logging : Cache-Control: public, max-stale=2419200
###Logging : <-- END HTTP (190-byte body)
###response.code() : 200, isSuccess() : true

第二个请求生成504错误.

###Logging : --> GET https://xxx HTTP/1.1
###Logging : Cache-Control: public, only-if-cached, max-stale=2147483647
###Logging : --> END GET
###OkHttpClient response : Response{protocol=http/1.1, code=504, message=Unsatisfiable Request (only-if-cached), url=https://xxx
###OkHttpClient response.cacheControl() : 
###OkHttpClient response.cacheResponse() : null
###Logging : <-- HTTP/1.1 504 Unsatisfiable Request (only-if-cached) (3ms)
###Logging : <-- END HTTP (0-byte body)

我试图删除Pragma.但是,同样的.和
使用帖子的结果,

缓存控制→无存储

Pragma→no-cache

为什么会导致此504不满足请求(仅限缓存)错误?
我该如何解决这个错误?

最佳答案 改造:2.0.0-beta4,okhttp:3.2.0

private NetworkingAction(){
    long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MB
    Cache cache = new Cache(getCacheDir(), SIZE_OF_CACHE);

    OkHttpClient okClient = new OkHttpClient
            .Builder()
            .addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
            .addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
            .cache(cache)
            .build();

    NetworkInterface service = new Retrofit.Builder()
            .baseUrl(ServerConstants.API_URL)
            .client(okClient)
            .build()
            .create(NetworkInterface.class);

    service.getSomething().clone().enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            Log.d("TAG", "onResponse: ");
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Log.d("TAG", "onFailure: " + t.getMessage());
        }
    });
}

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()
                    .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 (!NetworkUtils.isNetworkAvailable(VenueDetailsActivity.this)) {
            request = request.newBuilder()
                    .header("Cache-Control", "public, only-if-cached")
                    .build();
        }
        return chain.proceed(request);
    }
};
public static boolean isOnline() {
     ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo netInfo = cm.getActiveNetworkInfo();
     return netInfo != null && netInfo.isConnectedOrConnecting();

}

原答案:https://stackoverflow.com/a/36795214/5784294

点赞