How to log request and response body with Retrofit-Android?

折月煮酒 提交于 2019-11-27 10:35:10

I used setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG")), it helped me.
UPDATE.
You can also try for debug purpose use retrofit.client.Response as response model

Dhaval Jivani

Retrofit 2.0 :

UPDATE: @by Marcus Pöhls

Logging In Retrofit 2

Retrofit 2 completely relies on OkHttp for any network operation. Since OkHttp is a peer dependency of Retrofit 2, you won’t need to add an additional dependency once Retrofit 2 is released as a stable release.

OkHttp 2.6.0 ships with a logging interceptor as an internal dependency and you can directly use it for your Retrofit client. Retrofit 2.0.0-beta2 still uses OkHttp 2.5.0. Future releases will bump the dependency to higher OkHttp versions. That’s why you need to manually import the logging interceptor. Add the following line to your gradle imports within your build.gradle file to fetch the logging interceptor dependency.

compile 'com.squareup.okhttp3:logging-interceptor:3.9.0'

You can also visit Square's GitHub page about this interceptor

Add Logging to Retrofit 2

While developing your app and for debugging purposes it’s nice to have a log feature integrated to show request and response information. Since logging isn’t integrated by default anymore in Retrofit 2, we need to add a logging interceptor for OkHttp. Luckily OkHttp already ships with this interceptor and you only need to activate it for your OkHttpClient.

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();   
// add your other interceptors …
// add logging as last interceptor
httpClient.addInterceptor(logging);  // <-- this is the important line!
Retrofit retrofit = new Retrofit.Builder()  
        .baseUrl(API_BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(httpClient.build())
        .build();

We recommend to add logging as the last interceptor, because this will also log the information which you added with previous interceptors to your request.

Log Levels

Logging too much information will blow up your Android monitor, that’s why OkHttp’s logging interceptor has four log levels: NONE, BASIC, HEADERS, BODY. We’ll walk you through each of the log levels and describe their output.

further information please visit : Retrofit 2 — Log Requests and Responses

OLD ANSWER:

no logging in Retrofit 2 anymore. The development team removed the logging feature. To be honest, the logging feature wasn’t that reliable anyway. Jake Wharton explicitly stated that the logged messages or objects are the assumed values and they couldn’t be proofed to be true. The actual request which arrives at the server may have a changed request body or something else.

Even though there is no integrated logging by default, you can leverage any Java logger and use it within a customized OkHttp interceptor.

further information about Retrofit 2 please refer : Retrofit — Getting Started and Create an Android Client

Update for Retrofit 2.0.0-beta3

Now you have to use okhttp3 with builder. Also the old interceptor will not work. This response is tailored for Android.

Here's a quick copy paste for you with the new stuff.

1. Modify your gradle file to

  compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
  compile "com.squareup.retrofit2:converter-gson:2.0.0-beta3"
  compile "com.squareup.retrofit2:adapter-rxjava:2.0.0-beta3"
  compile 'com.squareup.okhttp3:logging-interceptor:3.0.1'

2. Check this sample code:

with the new imports. You can remove Rx if you don't use it, also remove what you don't use.

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.GsonConverterFactory;
import retrofit2.Retrofit;
import retrofit2.RxJavaCallAdapterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;

public interface APIService {

  String ENDPOINT = "http://api.openweathermap.org";
  String API_KEY = "2de143494c0b2xxxx0e0";

  @GET("/data/2.5/weather?appid=" + API_KEY) Observable<WeatherPojo> getWeatherForLatLon(@Query("lat") double lat, @Query("lng") double lng, @Query("units") String units);


  class Factory {

    public static APIService create(Context context) {

      OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
      builder.readTimeout(10, TimeUnit.SECONDS);
      builder.connectTimeout(5, TimeUnit.SECONDS);

      if (BuildConfig.DEBUG) {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        builder.addInterceptor(interceptor);
      }

      //Extra Headers

      //builder.addNetworkInterceptor().add(chain -> {
      //  Request request = chain.request().newBuilder().addHeader("Authorization", authToken).build();
      //  return chain.proceed(request);
      //});

      builder.addInterceptor(new UnauthorisedInterceptor(context));
      OkHttpClient client = builder.build();

      Retrofit retrofit =
          new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

      return retrofit.create(APIService.class);
    }
  }
}

Bonus

I know it's offtopic but I find it cool.

In case there's an http error code of unauthorized, here is an interceptor. I use eventbus for transmitting the event.

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.androidadvance.ultimateandroidtemplaterx.BaseApplication;
import com.androidadvance.ultimateandroidtemplaterx.events.AuthenticationErrorEvent;

import de.greenrobot.event.EventBus;
import java.io.IOException;
import javax.inject.Inject;
import okhttp3.Interceptor;
import okhttp3.Response;

public class UnauthorisedInterceptor implements Interceptor {

  @Inject EventBus eventBus;

  public UnauthorisedInterceptor(Context context) {
    BaseApplication.get(context).getApplicationComponent().inject(this);
  }

  @Override public Response intercept(Chain chain) throws IOException {
    Response response = chain.proceed(chain.request());
    if (response.code() == 401) {
      new Handler(Looper.getMainLooper()).post(() -> eventBus.post(new AuthenticationErrorEvent()));
    }
    return response;
  }
}

code take from https://github.com/AndreiD/UltimateAndroidTemplateRx (my project).

There doesn't appear to be a way to do basic + body, but you can use FULL and filter the headers you don't want.

RestAdapter adapter = new RestAdapter.Builder()
                          .setEndpoint(syncServer)
                          .setErrorHandler(err)
                          .setConverter(new GsonConverter(gson))
                          .setLogLevel(logLevel)
                          .setLog(new RestAdapter.Log() {
                              @Override
                              public void log(String msg) {
                                  String[] blacklist = {"Access-Control", "Cache-Control", "Connection", "Content-Type", "Keep-Alive", "Pragma", "Server", "Vary", "X-Powered-By"};
                                  for (String bString : blacklist) {
                                      if (msg.startsWith(bString)) {
                                          return;
                                      }
                                  }
                                  Log.d("Retrofit", msg);
                              }
                          }).build();

It appears that when overriding the log, the body is prefixed with a tag similar to

[ 02-25 10:42:30.317 25645:26335 D/Retrofit ]

so it should be easy to log basic + body by adjusting the custom filter. I am using a blacklist, but a whitelist could also be used depending on your needs.

below code is working for both with header and without header to print log request & response. Note: Just comment .addHeader() line if are not using header.

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                //.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .addNetworkInterceptor(new Interceptor() {

                    @Override

                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request().newBuilder()
                                // .addHeader(Constant.Header, authToken)
                                   .build();
                        return chain.proceed(request);
                    }
                }).build();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constant.baseUrl)
                .client(client) // This line is important
                .addConverterFactory(GsonConverterFactory.create())
                .build();

If you are using Retrofit2 and okhttp3 then you need to know that Interceptor works by queue. So add loggingInterceptor at the end, after your other Interceptors:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        if (BuildConfig.DEBUG)
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

 new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(new CatalogInterceptor(context))
                .addInterceptor(new OAuthInterceptor(context))
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//at the end
                .build();

I hope this code will help you to logging .
you just need to add interceptor in your Build.Gradle then make RetrofitClient .

First Step

Add this line to your build.gradle

 implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' 

Second Step

Make your Retrofit Client


   public class RetrofitClient {

    private Retrofit retrofit;
    private static OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();
    private static RetrofitClient instance = null;
    private static ApiServices service = null;
    private static HttpLoggingInterceptor logging =
            new HttpLoggingInterceptor();

    private RetrofitClient(final Context context) {
        httpClient.interceptors().add(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Interceptor.Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request.Builder builder = originalRequest.newBuilder().
                        method(originalRequest.method(), originalRequest.body());
                okhttp3.Response response = chain.proceed(builder.build());
                /*
                Do what you want
                 */
                return response;
            }
        });

        if (BuildConfig.DEBUG) {
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            // add logging as last interceptor
            httpClient.addInterceptor(logging);
        }

        retrofit = new Retrofit.Builder().client(httpClient.build()).
                baseUrl(Constants.BASE_URL).
                addConverterFactory(GsonConverterFactory.create()).build();
        service = retrofit.create(ApiServices.class);
    }


    public static RetrofitClient getInstance(Context context) {
        if (instance == null) {
            instance = new RetrofitClient(context);
        }
        return instance;
    }

    public ApiServices getApiService() {
        return service;
    }
}

Calling

RetrofitClient.getInstance(context).getApiService().yourRequestCall(); 

For android studio before 3.0 (using android motinor)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M

And for android studio from 3.0 and above (using android profiler as android monitor is replaced by android profiler)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!