Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cache okHTTP response from Web server?

I want to know how can okHTTP response from Web server (which returns json data) be cached?

I want my app to download all the data needed for RecycleView and cache it once the user runs the app first time - and avoid re-downloading and parsing all the same data from Web server, if data has not changed.

I tried to get response headers, but this is what I get:

Request URL: https://somedomain.com/wp-json/?categories=3&per_page=100&status=publish
Request Method: GET
Status Code: 200 OK
Remote Address: 176.28.12.139:443
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
Allow: GET
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json; charset=UTF-8
Date: Fri, 23 Mar 2018 15:41:23 GMT
Link: <https://somedomain.com/wp-json/>; rel="https://api.w.org/"
Server: nginx
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: PleskLin
X-Powered-By: PHP/7.1.15
X-Robots-Tag: noindex
X-WP-Total: 43
X-WP-TotalPages: 1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: hr,en-US;q=0.9,en;q=0.8,de;q=0.7,nb;q=0.6
Connection: keep-alive
Host: somedomain.com
Referer: https://somedomain.com/somedir/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
categories: 3
per_page: 100
status: publish

I have read that I could find ETAG or Last-Modified from the Server response to check for any changes, but as you can see there is no such thing.

Do you have any idea what to do if app only needs to download data at the first run - and after that only if the data has changed?

like image 543
unipin Avatar asked Mar 23 '18 15:03

unipin


People also ask

How does OkHttp caching work?

Basically: The client will send out something like timestamp or Etag of the last request. The server can then check if there is some data has changed in during that period of time or not. If nothing has changed, the server can just give a special code (304 -not modified) without sending the whole same response again.

What is interceptor in OkHttp?

Interceptors, according to the documentation, are a powerful mechanism that can monitor, rewrite, and retry the API call. So, when we make an API call, we can either monitor it or perform some tasks. In a nutshell, Interceptors function similarly to airport security personnel during the security check process.


2 Answers

You need cache interceptor like this:

public class CacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());

        CacheControl cacheControl = new CacheControl.Builder()
                .maxAge(15, TimeUnit.MINUTES) // 15 minutes cache
                .build();

        return response.newBuilder()
                .removeHeader("Pragma")
                .removeHeader("Cache-Control")
                .header("Cache-Control", cacheControl.toString())
                .build();
    }
}

Add this interceptor with Cache to your OkHttpClient like this:

File httpCacheDirectory = new File(applicationContext.getCacheDir(), "http-cache");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addNetworkInterceptor(new CacheInterceptor())
            .cache(cache)
            .build();
like image 72
shmakova Avatar answered Oct 24 '22 20:10

shmakova


Just add a cache to your OkHttp client. First, you'll need to create the cache:

int cacheSize = 10 * 1024 * 1024;
Cache cache = new Cache(cacheDirectory, cacheSize);

Note that with this code you're providing a cache with a size limit of 10MB. After this, you'll create your client with the following code:

OkHttpClient client = new OkHttpClient.Builder()
    .cache(cache)
    .build();

The client will honor cache related headers. You can relate to the official documentation for further details: https://github.com/square/okhttp/wiki/Recipes

like image 45
Gregorio Palamà Avatar answered Oct 24 '22 18:10

Gregorio Palamà