How to get data on OkHttp response code 304? - android

I read that a response with code 304 (Not Modified) should have no body. In that case, does OkHttp get the body from the cache, or shall we get it explicitely, i.e.
if reponseCode == 304:
body = <getDataFromCache>
In the latter case, how to get the data from the cache?
OkHttpClient client = new OkHttpClient();
File cacheDirectory = new File(context.getCacheDir(), "responses");
Cache cache = null;
try {
cache = new Cache(cacheDirectory, 10 * 1024 * 1024); // 10M
client.setCache(cache);
} catch (IOException e) {
Log.e("AbstractFeedIntentService", "Could not create http cache", e);
}
Request.Builder requestBuilder = new Request.Builder();
requestBuilder.url(url);
Request request = requestBuilder.build();
Call call = client.newCall(request);
Response response = call.execute();
// if code==304, does the response contain the data from the cache. If not, how to get it?

OkHttp will return data from its response cache.

Related

android okHttp no route to host exception why?

I am trying to call http url using okHttp library using the code below:
OkHttpClient client = new OkHttpClient();
Request.Builder builder = new Request.Builder();
builder.url(url);
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
return e+"";
}
The problem is the url is opened well and return data from browser of device, but when i try to call this function and passing the same url it return
java.net.NoRouteToHostException: No route to host

How to use cache response for Retrofit with OkHttp when network response returns error

I have a simple use case: Use network response when success. Else use cached response.
But the problem is that when network response is an error, the cache is also written with that response.
One of the suggestions I read is to do FORCE_CACHE in the Interceptor when networkResponse is not successful.
But since the networkResponse overrides cache with error, next time when you request (and the server still returns an error), the cache will have an error.
Below is my current snippet. I need to add logic for returning cached value when networkResponse is an error. Any suggestion will be greatly helpful.
private void setup() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(REWRITE_CACHE_CONTROL);
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
Cache cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024); // 10 MB
builder.cache(cache);
}
private static final Interceptor REWRITE_CACHE_CONTROL = new Interceptor() {
#Override
public okhttp3.Response intercept(#NonNull Chain chain) throws IOException {
Request request = chain.request();
if (!hasAConnection()) {
request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
}
return chain.proceed(request);
}
};

How Retrofit with OKHttp use cache data when offline

I want to Retrofit with OkHttp uses cache when is no Internet.
I prepare OkHttpClient like this:
RestAdapter.Builder builder= new RestAdapter.Builder()
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json;versions=1");
if (MyApplicationUtils.isNetworkAvaliable(context)) {
int maxAge = 60; // read from cache for 1 minute
request.addHeader("Cache-Control", "public, max-age=" + maxAge);
} else {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
request.addHeader("Cache-Control",
"public, only-if-cached, max-stale=" + maxStale);
}
}
});
and setting cache like this:
Cache cache = null;
try {
cache = new Cache(httpCacheDirectory, 10 * 1024 * 1024);
} catch (IOException e) {
Log.e("OKHttp", "Could not create http cache", e);
}
OkHttpClient okHttpClient = new OkHttpClient();
if (cache != null) {
okHttpClient.setCache(cache);
}
and I checked on rooted device, that in cache directory are saving files with the "Response headers" and Gzip files.
But I don't get the correct answer from retrofit cache in offline, although in GZip file is coded my correct answer. So how can I make Retrofit can read GZip file and how can he know which file it should be (because I have a few files there with other responses) ?
I have simlar problem in my company :)
The problem was on server side. In serwer response i have:
Pragma: no-cache
So when i removed this everything starts working. Before i removed it i get all the time such exceptions: 504 Unsatisfiable Request (only-if-cached)
Ok so how implementation on my side looks.
OkHttpClient okHttpClient = new OkHttpClient();
File httpCacheDirectory = new File(appContext.getCacheDir(), "responses");
Cache cache = new Cache(httpCacheDirectory, maxSizeInBytes);
okHttpClient.setCache(cache);
OkClient okClient = new OkClient(okHttpClient);
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setEndpoint(endpoint);
builder.setClient(okClient);
If you have problems in testing on which side is problem (server or app). You can use such feauture to set headers received from server.
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control",
String.format("max-age=%d", 60))
.build();
}
};
and simply add it:
okHttpClient.networkInterceptors().add(REWRITE_CACHE_CONTROL_INTERCEPTOR);
Thanks to that as you can see i was able to remove Pragma: no-cache header for test time.
Also i suggest you to read about Cache-Control header:
max-age,max-stale
Other usefull links:
List of HTTP header fields
Cache controll
Another sample code

How to use disk cache to cache ParseFile

I'm using Parse and Picasso to load images onto ParseImageViews. Is there anything I'm missing to cache the parse files? My listview seems to be fetching the file from server every time and using the disk cache that comes with Picasso.
I don't see cache-control: max-age parameter in the http responses of downloads of parse files(from amazon s3 where parse stores them)
I have the following code,
final ParseImageView pic = viewHolder.img;
pic.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
ParseFile f = parseObject.getParseFile("image");
Picasso.with(mContext).load(f.getUrl()).into(pic);
Any help would be appreciated. Thanks.
Use OkHttp client as http transport for Picasso and specify disk and memory cache size:
OkHttpClient okHttp = new OkHttpClient();
Cache cache = new Cache(ctx.getCacheDir(), cacheSize);
okHttp.setCache(cache);
// Use OkHttp as downloader
Downloader downloader = new OkHttpDownloader(okHttp);
mPicasso = new Picasso.Builder(getApplicationContext())
.downloader(downloader)).memoryCache(new LruCache(size)).build();
Setup request interceptor (example) for OkHttp client:
// Add Cache-Control to origin response (force cache)
client.networkInterceptors().add(new Interceptor() {
private com.squareup.okhttp.Request request;
private Response response;
private String requestUrl;
#Override
public Response intercept(Chain c) throws IOException {
request = c.request();
response = c.proceed(request);
if (!request.cacheControl().noStore()
&& !response.cacheControl().noStore()) {
requestUrl = request.urlString();
// Do not cache keys or playlists
response = response
.newBuilder()
.header("Cache-Control","public, max-age=42000").build();
}
return response;
}
});

In Android okhttpclient not caching public cache-control

I am using below code to cache in Android device to collect the response and get from cache till the max age expires. When i use "public" I was able to see the response cached in my application installed folder(/data/data/app_folder).
I tried all below none of them works for "private" but when I change to "public" all my solutions i tried works.
But I need to make it to work for "private". Am I missing something.
Header I will receive "Cache-Control", "private,max-age=120"
Solution 1:
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
HttpResponseCache httpResponseCache = null;
try {
httpResponseCache = new HttpResponseCache(httpCacheDirectory, 10 * 1024 * 1024);
} catch (IOException e) {
Log.e("Retrofit", "Could not create http cache", e);
}
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setResponseCache(httpResponseCache);
Solution 2:
And I am using Retrofit library, an Android client.
Cache cache = new Cache(cacheDirectory, cacheSize);
client = new OkHttpClient();
client.setCache(cache);

Categories

Resources