Skip to content

Instantly share code, notes, and snippets.

@voghDev
Created October 29, 2015 12:51
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save voghDev/0bd7050a675ee0f31e51 to your computer and use it in GitHub Desktop.
Save voghDev/0bd7050a675ee0f31e51 to your computer and use it in GitHub Desktop.
retrofit2 interceptor that logs the raw JSON response from API. After that it clones it and returns a sane copy that other classes can consume.
import android.util.Log;
import com.appandweb.prjtestdrivendev.BuildConfig;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import java.io.IOException;
public class LogJsonInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
String rawJson = response.body().string();
Log.d(BuildConfig.APPLICATION_ID, String.format("raw JSON response is: %s", rawJson));
// Re-create the response before returning it because body can be read only once
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), rawJson)).build();
}
}
@voghDev
Copy link
Author

voghDev commented Oct 29, 2015

Sample code to use this interceptor:

OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new LogJsonInterceptor());
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

@voghDev
Copy link
Author

voghDev commented Apr 13, 2016

Update to make it work on retrofit 2.0.1 + okhttp3:

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new LogJsonInterceptor());
Retrofit retrofit = new Retrofit.Builder()
         .baseUrl(getEndPoint())
         .addConverterFactory(GsonConverterFactory.create())
         .client(httpClient.build())
         .build();

@aliang228
Copy link

没必要制造额外的一个请求。

/**
 * HttpInterceptor
 */
public class HttpInterceptor implements Interceptor {
    private static final Charset UTF8 = Charset.forName("UTF-8");

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Logger.d(BuildConfig.APPLICATION_ID, "call ==> " + request.url());
        Response response = chain.proceed(request);
        ResponseBody responseBody = response.body();
        BufferedSource source = responseBody.source();
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Logger.d(BuildConfig.APPLICATION_ID, "ret ==> " + buffer.clone().readString(UTF8).toString());
        return response;
    }
}

可以参考HttpLoggingInterceptor源码

@pathwayasis
Copy link

Many thanks for the tips but What about the request? How do we print log of the request in JSON?

@thanhbinh84
Copy link

This helps to format output more readable

public class LogJsonInterceptor implements Interceptor {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();

        Response response = chain.proceed(request);
        String rawJson = response.body().string();

        try {
            Object object = new JSONTokener(rawJson).nextValue();
            String jsonLog = object instanceof JSONObject
                    ? ((JSONObject) object).toString(4)
                    : ((JSONArray) object).toString(4);
            Log.d("jsonLog", jsonLog);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        // Re-create the response before returning it because body can be read only once
        return response.newBuilder()
                .body(ResponseBody.create(response.body().contentType(), rawJson)).build();
    }
}

@VijayBest
Copy link

Thanks so much sir You save My time

@Abdelalim-dev
Copy link

Thanks a lot, saved me the trouble

@YugandharVadlamudi
Copy link

This solution working Thanks. @thanhbinh84

@voghDev
Copy link
Author

voghDev commented Jun 4, 2020

没必要制造额外的一个请求。

/**
 * HttpInterceptor
 */
public class HttpInterceptor implements Interceptor {
    private static final Charset UTF8 = Charset.forName("UTF-8");

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Logger.d(BuildConfig.APPLICATION_ID, "call ==> " + request.url());
        Response response = chain.proceed(request);
        ResponseBody responseBody = response.body();
        BufferedSource source = responseBody.source();
        source.request(Long.MAX_VALUE); // Buffer the entire body.
        Buffer buffer = source.buffer();
        Logger.d(BuildConfig.APPLICATION_ID, "ret ==> " + buffer.clone().readString(UTF8).toString());
        return response;
    }
}

可以参考HttpLoggingInterceptor源码

Hi @aliang228, regarding your code proposal. Couldn't this Long.MAX_VALUE be improved? according to .request() documentation:

  /**
   * Returns true when the buffer contains at least {@code byteCount} bytes, expanding it as
   * necessary. Returns false if the source is exhausted before the requested bytes can be read.
   */
  boolean request(long byteCount) throws IOException;

This means that you would be requesting a buffer of 9.223.372.036.854.775.807 bytes on every HTTP request intercepted by this HttpInterceptor. Do you find this reasonable? or could it be improved?

Thanks for the proposal!

@panrongfu
Copy link

thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment