web-dev-qa-db-ja.com

Retrofit-Androidでリクエストとレスポンスの本文を記録する方法は?

完全な要求/応答本文を記録するためのRetrofit APIに関連するメソッドが見つかりません。プロファイラーで何らかの助けを期待していました(ただし、応答に関するメタデータのみを提供します)。 Builderでログレベルを設定しようとしましたが、これも役に立ちません:

RestAdapter adapter = (new RestAdapter.Builder()).
                setEndpoint(baseUrl).
                setRequestInterceptor(interceptor).
                setProfiler(profiler).
                setClient(client).
                setExecutors(MyApplication.getWebServiceThreadPool()).
                setLogLevel(LogLevel.FULL).
                setLog(new RestAdapter.Log() {
                    @Override
                    public void log(String msg) {
                        Log.i(TAG, msg);
                    }
                }).
                build();

編集:このコードは現在機能しています。それが以前に機能しなかった理由がわかりません。おそらく、古いバージョンのレトロフィットを使用していたからでしょう。

112
Jaguar

setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG"))を使用しましたが、助けてくれました。
更新。
応答モデルとしてretrofit.client.Responseを使用してデバッグすることもできます

87
Alex Dzeshko

Retrofit 2.0

更新:@by MarcusPöhls

Retrofit 2へのログイン

Retrofit 2は、すべてのネットワーク操作でOkHttpに完全に依存しています。 OkHttpはRetrofit 2のピア依存関係であるため、Retrofit 2が安定リリースとしてリリースされたら、追加の依存関係を追加する必要はありません。

OkHttp 2.6.0には、内部依存関係としてロギングインターセプターが付属しており、Retrofitクライアントに直接使用できます。 Retrofit 2.0.0-beta2は引き続きOkHttp 2.5.0を使用します。将来のリリースでは、OkHttpの上位バージョンへの依存関係が強化されます。そのため、ロギングインターセプターを手動でインポートする必要があります。 build.gradleファイル内のgradleインポートに次の行を追加して、ロギングインターセプターの依存関係を取得します。

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

このインターセプターについてSquareのGitHubページにアクセスすることもできます

Retrofit 2にログを追加

アプリの開発中およびデバッグの目的で、リクエストとレスポンスの情報を表示するログ機能を統合すると便利です。ロギングはRetrofit 2ではデフォルトで統合されなくなったため、OkHttpのロギングインターセプターを追加する必要があります。幸いなことに、OkHttpにはこのインターセプターが既に付属しており、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();

最後のインターセプターとしてロギングを追加することをお勧めします。これにより、以前のインターセプターでリクエストに追加した情報もログに記録されるためです。

ログレベル

あまりにも多くの情報を記録すると、Androidモニターが爆破されるため、OkHttpのロギングインターセプターには、NONE、BASIC、HEADERS、BODYの4つのログレベルがあります。各ログレベルについて説明し、その出力について説明します。

詳細については、以下をご覧ください: Retrofit 2 —ログリクエストとレスポンス

古い回答:

retrofit 2でのロギングはもうありません。開発チームはログ機能を削除しました。正直なところ、とにかくログ機能はそれほど信頼できませんでした。 Jake Whartonは、ログに記録されたメッセージまたはオブジェクトは想定された値であり、真であると証明できないと明示的に述べました。サーバーに到着する実際のリクエストは、リクエストの本体または何かが変更されている場合があります。

デフォルトでは統合されたロギングはありませんが、任意のJavaロガーを活用して、カスタマイズされたOkHttpインターセプター内で使用できます。

retrofit 2の詳細については、以下を参照してください。 Retrofit —はじめにAndroidクライアントの作成

102
Dhaval Jivani

Retrofit 2.0.0-beta3の更新

次に、ビルダーでokhttp3を使用する必要があります。また、古いインターセプターは機能しません。この応答は、Android用に調整されています。

新しいものを簡単にコピーして貼り付けます。

1。 gradleファイルをに変更します

  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。このサンプルコードを確認してください:

新しいインポートで。 Rxを使用しない場合は削除でき、使用しないものも削除できます。

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);
    }
  }
}

ボーナス

私はそれがオフトピックであることを知っていますが、それはクールだと思います。

Httpエラーコードunauthorizedがある場合、ここにインターセプターがあります。イベントの送信にはイベントバスを使用します。

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;
  }
}

コードは https://github.com/AndreiD/UltimateAndroidTemplateRx (私のプロジェクト)から取得します。

30
OWADVL

基本的な+ボディを行う方法はないようですが、FULLを使用して、不要なヘッダーをフィルタリングできます。

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();

ログを上書きすると、本文の前に次のようなタグが付けられます

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

そのため、カスタムフィルタを調整することで、基本+本体を簡単に記録できるはずです。ブラックリストを使用していますが、必要に応じてホワイトリストを使用することもできます。

9
Xeridea

以下のコードは、ヘッダーありとヘッダーなしの両方でログ要求と応答を印刷するために機能しています。 注:ヘッダーを使用していない場合は、.addHeader()行のみコメントしてください。

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();
3
Mukesh Parmar

Retrofit2とokhttp3を使用している場合、Interceptorがキューごとに機能することを知る必要があります。したがって、最後に、他のインターセプターの後にloggingInterceptorを追加します。

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();
2
NickUnuchek

このコードがロギングに役立つことを願っています。
インターセプターをBuild.Gradleに追加して、RetrofitClientを作成するだけです。

最初の一歩

この行をbuild.gradleに追加します

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

第二段階

レトロフィットクライアントを作成する


   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;
    }
}

呼び出し中

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

2
Talha Bilal

ZoomX — Android Logger Interceptor は、問題の解決に役立つ優れたインターセプターです。

0

3.0より前のAndroid studioの場合(Android motinorを使用)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M

3.0以降のAndroid studioの場合(AndroidプロファイラーをAndroidモニターとして使用すると、Androidプロファイラーに置き換えられます)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-Android-studio-profiler

0
shehzy