Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/210.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android HTTP 504不可满足的请求(仅当缓存时)_Android_Retrofit_Okhttp - Fatal编程技术网

Android HTTP 504不可满足的请求(仅当缓存时)

Android HTTP 504不可满足的请求(仅当缓存时),android,retrofit,okhttp,Android,Retrofit,Okhttp,2.2.0和okhttp3.9.1脱机缓存不工作,当我请求脱机数据时,将抛出一个异常,即HTTP 504不可满足请求(仅当缓存时)。数据正在从internet加载到设备中,但脱机模式无法检索数据 演示: 下面的代码描述了API接口 public class TestApi { private static TestService testService; private static final String TEST_URL = "https://httpbin.org

2.2.0和okhttp3.9.1脱机缓存不工作,当我请求脱机数据时,将抛出一个异常,即HTTP 504不可满足请求(仅当缓存时)。数据正在从internet加载到设备中,但脱机模式无法检索数据

演示:

下面的代码描述了API接口

public class TestApi {


    private static TestService testService;

    private static final String TEST_URL = "https://httpbin.org/";


    public static TestService getTestService() {

        if(testService == null) {
            synchronized (TestApi.class) {
                if(testService == null) {
                    testService = XApi.getInstance().getRetrofit(TEST_URL, true).create(TestService.class);
                }
            }
        }
        return testService;
    }

}
下面的代码描述了API服务

public interface TestService {

    @GET("/cache/60")
    Flowable<TestBean> getTestDate();

}
最后,向OkHttpClient.Builder添加一个拦截器

Retrofit.Builder builder = new Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(getClient(baseUrl, provider))
    .addConverterFactory(GsonConverterFactory.create());

builder.addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR);
builder.addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE);
我不知道怎么解决它


希望有人能帮助我

我仍然不太明白您到底想做什么,但从一个更简单的可执行示例开始,下面的代码有什么问题

package com.baulsupp.oksocial;

import okhttp3.*;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.http.GET;

import java.io.File;
import java.io.IOException;

public class TestRequest {
    private static boolean connected = true;

    public interface TestService {
        @GET("/cache/60")
        Call<String> getTestDate();
    }

    public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (isConnected()) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
            } else {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
            }
            Response response = chain.proceed(request);

            System.out.println("network: " + response.networkResponse());
            System.out.println("cache: " + response.cacheResponse());

            return response;
        }
    };

    private static boolean isConnected() {
        return connected;
    }

    public static void main(String[] args) throws IOException {

        OkHttpClient.Builder clientBuilder =
                new OkHttpClient.Builder().cache(new Cache(new File("/tmp/http"), 10 * 1024 * 1024));

        clientBuilder.addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE);

        Retrofit builder = new Retrofit.Builder()
                .addConverterFactory(ScalarsConverterFactory.create())
                .baseUrl("https://httpbin.org/")
                .client(clientBuilder.build())
                .build();

        TestService service = builder.create(TestService.class);

        connected = true;

        String online = service.getTestDate().execute().body();
        System.out.println(online);

        connected = false;

        String offline = service.getTestDate().execute().body();
        System.out.println(offline);
    }
}
仅当缓存时: 由客户端设置,指示响应“不使用网络”。缓存应使用存储的响应或使用504状态代码响应。不应设置条件标头,例如“如果没有匹配项”。如果服务器将缓存设置为响应的一部分,则不会产生任何效果。(参考:)


因此,“仅当缓存”是缓存请求指令,不应在响应头中使用。但是您可以尝试将(“缓存控制”、“仅当缓存时”max stale“
”)添加到请求头,以允许仅缓存过时的响应。

代码的格式使得在不进行实质性重写的情况下很难重现。我甚至不认为Reformation.Builder有addNetworkInterceptor方法。所以这里的基本问题是CacheControl是一个客户端API,不是为手动设置http头而设计的。因此,将其作为网络请求的一部分发送是错误的,因为远程服务器无法满足您的“仅缓存”任务。哈哈!!,我喜欢你回答的方式。(很好用,谢谢)
package com.baulsupp.oksocial;

import okhttp3.*;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.http.GET;

import java.io.File;
import java.io.IOException;

public class TestRequest {
    private static boolean connected = true;

    public interface TestService {
        @GET("/cache/60")
        Call<String> getTestDate();
    }

    public static final Interceptor REWRITE_RESPONSE_INTERCEPTOR_OFFLINE = new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (isConnected()) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
            } else {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
            }
            Response response = chain.proceed(request);

            System.out.println("network: " + response.networkResponse());
            System.out.println("cache: " + response.cacheResponse());

            return response;
        }
    };

    private static boolean isConnected() {
        return connected;
    }

    public static void main(String[] args) throws IOException {

        OkHttpClient.Builder clientBuilder =
                new OkHttpClient.Builder().cache(new Cache(new File("/tmp/http"), 10 * 1024 * 1024));

        clientBuilder.addInterceptor(REWRITE_RESPONSE_INTERCEPTOR_OFFLINE);

        Retrofit builder = new Retrofit.Builder()
                .addConverterFactory(ScalarsConverterFactory.create())
                .baseUrl("https://httpbin.org/")
                .client(clientBuilder.build())
                .build();

        TestService service = builder.create(TestService.class);

        connected = true;

        String online = service.getTestDate().execute().body();
        System.out.println(online);

        connected = false;

        String offline = service.getTestDate().execute().body();
        System.out.println(offline);
    }
}
network: Response{protocol=http/1.1, code=200, message=OK, url=https://httpbin.org/cache/60}
cache: null
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Cache-Control": "no-cache", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "okhttp/3.9.1"
  }, 
  "origin": "82.5.95.16", 
  "url": "https://httpbin.org/cache/60"
}

network: null
cache: Response{protocol=http/1.1, code=200, message=OK, url=https://httpbin.org/cache/60}
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Cache-Control": "no-cache", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "okhttp/3.9.1"
  }, 
  "origin": "82.5.95.16", 
  "url": "https://httpbin.org/cache/60"
}