6

I make some POST requests to my server with OkHttp. This works fine. Now I want use the cache of OkHttp to cache the responses of the requests and use them when the device is offline. I tried many solutions from other questions, but none of them work.

I use OkHttp 2.5.0

With the code below, I get a valid response, when the device has internet access. But if I turn the internet off, it throws a java.net.UnknownHostException: Unable to resolve host "example.com": No address associated with hostname

Here is my current code, which does not work:

Interceptor for rewriting the cache headers:

private final Interceptor mCacheControlInterceptor = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        if (isOnline()) {
            request.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=7887")
                    .build();
        } else {
            request.newBuilder()
                    .header("Cache-Control", "public, max-stale=2419200")
                    .build();
        }

        Response response = chain.proceed(request);

        // Re-write response CC header to force use of cache
        return response.newBuilder()
                .header("Cache-Control", "public, max-age=86400") // 1 day
                .build();
    }
};

Method to get the client:

private OkHttpClient getHttpClient() {
    if (mHttpClient == null) {
        mHttpClient = new OkHttpClient();
        mHttpClient.setConnectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS);

        File cacheDir = mContext.getDir(CACHE_NAME, Context.MODE_PRIVATE);
        mHttpClient.setCache(new Cache(cacheDir, CACHE_SIZE));

        mHttpClient.networkInterceptors().add(mCacheControlInterceptor);
    }

    return mHttpClient;
}

Make the request:

RequestBody body = RequestBody.create(TEXT, data);
Request request = new Request.Builder()
        .url(url)
        .post(body)
        .build();
Response response = getHttpClient().newCall(request).execute();
Auroratic
  • 462
  • 8
  • 25

1 Answers1

13

You can't cache POST requests with OkHttp’s cache. You’ll need to store them using some other mechanism.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • ... or use GET requests. – Jesse Wilson Sep 23 '15 at 02:25
  • 1
    can you show me any documentation or official notes on this ? – droidev Nov 18 '15 at 08:46
  • 2
    @JesseWilson is right, here you have the link to the code that ignore any other verb that it's not a GET: [okhttp3/Cache.java#L230](https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/Cache.java#L230]) – Juan Saravia Mar 29 '16 at 15:06
  • 2
    Is there any way to cache `POST` requests other than OkHttp but not removing Retrofit implementation? – Malwinder Singh Aug 28 '17 at 07:13
  • 2
    This still true in 2022: [okhttp3/Cache.kt](https://github.com/square/okhttp/blob/1ed8308feae1cf2f61950a993aa43116f2a50fc7/okhttp/src/jvmMain/kotlin/okhttp3/Cache.kt#L210) – Eduardo Dobay Mar 26 '22 at 18:16