Retrofit: call.enqueue - Api endpoint is called 2 times implicitly

Created on 28 Oct 2015  路  7Comments  路  Source: square/retrofit

        Log.d(TAG, "Calling REST");        

        Call<JsonObject> call = RestClient.getApiService().registerUser();
        call.enqueue(new Callback<JsonObject>()
        {
            @Override
            public void onResponse(Response<JsonObject> response, Retrofit retrofit)
            {
                Log.d(TAG, "REST Response : " + response.body());
            }

            @Override
            public void onFailure(Throwable t)
            {
                Log.e(TAG, "REST Error : " + t.getMessage());
            }
       });

Output in Android Studio
1) Calling REST
2) REST Response : {"status":"success"}

If I use Postman (REST Client) to call the api endpoint, its called only once. But with the above code, when executed once, the api endpoint is called twice.

I am trying to format the received data in normal com.google.gson.JsonObject as I don't need the hassles of maintaing Models in Android code.

What's more weird is, first 'Calling REST' gets onto console. Then 2 requests are made and only after second request, 'REST Response : {"status":"success"}' gets onto console.

I am using Retrofit 2.0.0-beta2.

Edit - My Bad, the interceptor fired another request, hence it was being called 2 times.

        OkHttpClient client = new OkHttpClient();
        client.interceptors().add(new Interceptor()
        {
            @Override
            public Response intercept(Chain chain) throws IOException
            {
                Response response = chain.proceed(chain.request());

                // Do anything with response here

                Request newRequest = chain.request().newBuilder().addHeader("User-Agent", Constants.APP_NAME).build();
                return chain.proceed(newRequest);
            }
        });

Most helpful comment

I had an HTTPLogger and chain.proceed(..) in one interceptor itself. So assuming that HTTPLogger internally also calls chain.proceed() which thus makes two requests, I added a networkinterceptor and moved the HTTPLogger to the network interceptor and my custom apikey chain.proceed(...) In other interceptor. Which worked as a charm and the API was called only once internally. Thus you need to look for code which can possibly call the chain.proceed(..) method internally. Which makes a new request.

All 7 comments

Had the same issue. Thank you so much for posting it here.

What did you do to make only one request?
with Interceptor on

I had an HTTPLogger and chain.proceed(..) in one interceptor itself. So assuming that HTTPLogger internally also calls chain.proceed() which thus makes two requests, I added a networkinterceptor and moved the HTTPLogger to the network interceptor and my custom apikey chain.proceed(...) In other interceptor. Which worked as a charm and the API was called only once internally. Thus you need to look for code which can possibly call the chain.proceed(..) method internally. Which makes a new request.

https://github.com/square/retrofit/issues/2761
Can anybody shade the light? having same issue.

Can any body post code Solution for same

any who come after, the solution for me was to remove chain.proceed calls leave only the one that add the header
fun createHttpClientBuilder(loggingInterceptor: HttpLoggingInterceptor, context: Context): OkHttpClient.Builder {
val httpClient = OkHttpClient.Builder()
.connectTimeout(ConfigurationFile.NetworkSettings.REQUEST_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(ConfigurationFile.NetworkSettings.REQUEST_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(ConfigurationFile.NetworkSettings.REQUEST_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(loggingInterceptor)
// .addInterceptor(AuthorizationInterceptorImpl(context))
.addInterceptor { chain: Interceptor.Chain ->
val original = chain.request()
//val response = chain.proceed(original)
val requestBuilder = original.newBuilder()
.addHeader(context.resources.getString(R.string.accept), ConfigurationFile.NetworkSettings.CONTENT_TYPE)
.addHeader(context.resources.getString(R.string.content_type), ConfigurationFile.NetworkSettings.CONTENT_TYPE)
.addHeader("fireBaseToken", fireBaseToken.value.firebaseToken)
val request = requestBuilder.build()
chain.proceed(request)
}
return httpClient

long story short chain.proceed create another request maybe

I had an HTTPLogger and chain.proceed(..) in one interceptor itself. So assuming that HTTPLogger internally also calls chain.proceed() which thus makes two requests, I added a networkinterceptor and moved the HTTPLogger to the network interceptor and my custom apikey chain.proceed(...) In other interceptor. Which worked as a charm and the API was called only once internally. Thus you need to look for code which can possibly call the chain.proceed(..) method internally. Which makes a new request.

@shahsurajk Thanks save me a lot of trouble

Was this page helpful?
0 / 5 - 0 ratings