Okhttp: How to retry call with interceptors mechanism?

Created on 15 Jan 2015  ·  8Comments  ·  Source: square/okhttp

In wiki says "Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls". How I can retry call if I receive json like a {"status":2,"response":""}? Where status == 2 means un unready response.

Most helpful comment

Your interceptor is consuming the response body stream. You can't do this without providing a new response body for Retrofit to consume.

All 8 comments

After parsing the result, just call chain.proceed() again with the same, updated, or completely new request.

Thanks. But I have another problem with parsing status in interceptor. I have interceptor:

private static Interceptor statusInterceptor = new Interceptor() {
        @Override
        public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {

            com.squareup.okhttp.Response originalResponse = chain.proceed(chain.request());
            if (originalResponse.code() == HttpURLConnection.HTTP_OK) {
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode jsonNode = objectMapper.readTree(originalResponse.body().charStream());
                if (jsonNode.get("status").asInt() == 2) {
                    // handling
                }
            return originalResponse;
        }
    };

and I receive exception in objectMapper.readTree():

01-16 11:34:31.911    2097-2119/ru.gnivc.lkip D/Retrofit﹕ java.io.IOException: closed
            at okio.RealBufferedSource$1.read(RealBufferedSource.java:294)
            at java.io.InputStream.read(InputStream.java:162)
            at retrofit.Utils.streamToBytes(Utils.java:43)
            at retrofit.Utils.readBodyToBytesIfNecessary(Utils.java:81)
            at retrofit.RestAdapter.logAndReplaceResponse(RestAdapter.java:483)
            at retrofit.RestAdapter.access$500(RestAdapter.java:107)
            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:338)
            at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
            at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
            at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at retrofit.Platform$Android$2$1.run(Platform.java:142)
            at java.lang.Thread.run(Thread.java:841)
01-16 11:34:31.911    2097-2119/ru.gnivc.lkip D/Retrofit﹕ ---- END ERROR

Our server send response successfuly and don't close connection.

Main problem is this IOException throwed by ResponseBody methods produce RetrofitError. But this is not error case, I am able to read status. How I can supress this IOException?

Your interceptor is consuming the response body stream. You can't do this without providing a new response body for Retrofit to consume.

return originalResponse.newBuilder().build();

Right?

You need to create a new body. Mostly likely with a cloned or copied Buffer which was created from buffering the initial response so you could parse it.

Buffer buffer = new Buffer();
buffer.writeAll(originalResponse.body().source());

ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(buffer.inputStream());

It works. Thanks!

how retry will be handled when two api call come at same time

Was this page helpful?
0 / 5 - 0 ratings