11

I'm try to do Android offline caching method using OkHttp. The flow is like this:

  1. I send an HTTP request with an ETag empty string at header field if-none-catched to the server, and the server returns a proper ETag.
  2. Then I store the ETag and cache the response.
  3. Next time when I fire the same service call I get the same ETag and set it to the HTTP request header and the server will return HTTP 304 if the ETag is the same.

My issue now is how can I store and retrieve the ETag? Does OkHttp default will handle or I need store at SQLite? I keep looking on Google about OkHttp implement ETag sample code but all I get is just normal caching method. Link I refer:

  1. I'm trying to use Java's HttpURLConnection to do a "conditional get", but I never get a 304 status code
  2. https://github.com/square/okhttp/wiki/Interceptors
  3. Correct way of setting up cache for OkHttp in Android
  4. https://gist.github.com/polbins/1c7f9303d2b7d169a3b1#file-restcontroller-java-L45

so far what I achieved is only cache for 1st time service call, but never get latest data from server anymore. Appreciate if anyone can provide some guidance or found any good example of handle ETag and if-none-catch dynamically for OkHttp to share with. Any clarification feel free to ask.

JJD
  • 50,076
  • 60
  • 203
  • 339
cloud
  • 173
  • 1
  • 2
  • 8

1 Answers1

11

You just need to enable OkHttp’s response cache. It’ll use the ETag if your webserver returns one.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
  • which part of the code turn on/ enable okhttp response cache? i do set cache object into my okhttpClient but it didn't affect my response, and i don't even get etag back as header – cloud Apr 26 '16 at 03:21
  • 1
    Is your server sending ETags? The cache will use ’em on subsequent requests for the same URL. – Jesse Wilson Apr 26 '16 at 12:04
  • ya just updated and server send ETags now, now i got 2 issue: one is i cannot get new etag from previous response to append to next request; another is i try to hardcode request ETags for testing, i successfully get 304 from response but unable to read cache response. And also server response with header Cache-Control "no-cache, max-age=0", does this affect? – cloud Apr 26 '16 at 13:05
  • If you use OkHttp’s built-in cache, it’ll handle the ETags for you completely on its own. You don’t need to look up the ETags, that’s the cache’s job. – Jesse Wilson Apr 28 '16 at 04:37
  • 1
    One downside to OkHttp's support for ETags is that OkHttp never "refreshes" the cache's expiration. So once it is expired, it will never use the cache until it is updated. This will only occur if the resource has been updated (etags are different and 200 response is returned vs. 304).. This means that the OkHttp client will continue to go to the network for each subsequent request as long as it continues to get a 304 response. The HTTP spec is vague on how clients should handle this scenario, so I don't think it's a bug. But it does defeat the purpose of a cache if I keep hitting the network. – Steven Pena Aug 27 '16 at 20:37
  • 1
    We have a test that shows that OkHttp at least partially supports this behavior. @StevenPena could you please show a similar test that demonstrates the behavior you’re seeing? https://github.com/square/okhttp/blob/master/okhttp-tests/src/test/java/okhttp3/CacheTest.java#L1825 – Jesse Wilson Aug 29 '16 at 03:44
  • 1
    That test is what I was hoping to have happen. Unfortunately it doesn't work this way in Android. I'll put up a test project using the AndroidJUnit test runner and share that. – Steven Pena Aug 29 '16 at 06:33
  • @JesseWilson I would appreciate if you could take the time to mention the ETag usage in the [*Response Caching* section](https://github.com/square/okhttp/wiki/Recipes#response-caching) of the wiki page. – JJD Jun 18 '17 at 14:49
  • The link seems broken. Is https://square.github.io/okhttp/recipes/#response-caching the new one? – palacsint Aug 29 '19 at 09:19
  • yep can't find info on that – Fabio Jul 21 '20 at 00:47