348

リクエストで送信されている正確な JSON を取得しようとしています。これが私のコードです:

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
   @Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
      Request request = chain.request();
      Log.e(String.format("\nrequest:\n%s\nheaders:\n%s",
                          request.body().toString(), request.headers()));
      com.squareup.okhttp.Response response = chain.proceed(request);
      return response;
   }
});
Retrofit retrofit = new Retrofit.Builder()
   .baseUrl(API_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(client).build();

しかし、ログにはこれしか表示されません。

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json

Retrofit 1 で使用していたsetLog()とが削除された場合、適切なログ記録を行うにはどうすればよいですか?setLogLevel()

4

22 に答える 22

766

Retrofit 2 では、 HttpLoggingInterceptorを使用する必要があります。

に依存関係を追加しbuild.gradleます。2019 年 10 月現在の最新バージョンは次のとおりです。

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

Retrofit次のようなオブジェクトを作成します。

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://backend.example.com")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

return retrofit.create(ApiClient.class);

非推奨の警告が表示された場合は、次のように変更setLevelしてください。

interceptor.level(HttpLoggingInterceptor.Level.BODY);

上記の解決策は、によって設定された古いものと非常によく似たlogcatメッセージを提供します

setLogLevel(RestAdapter.LogLevel.FULL)

の場合java.lang.ClassNotFoundException

古い Retrofit バージョンでは、古いlogging-interceptorバージョンが必要になる場合があります。詳細については、コメント セクションを参照してください。

于 2015-10-21T10:23:32.657 に答える
38

私はあなたと出会い、本の著者に尋ねようとしましたRetrofit: Love working with APIs on Android (ここにリンクがあります) (いいえ! 私はそれらのためにいくつかの広告を作成していません....しかし、彼らは本当に素晴らしいですみんな:) そして、著者はすぐに私に返信しました.Retrofit 1.9とRetrofit 2.0-betaの両方のLogメソッドで。

Retrofit 2.0-beta のコードは次のとおりです。

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(Level.BODY);

OkHttpClient httpClient = new OkHttpClient();  
// add your other interceptors …

// add logging as last interceptor
httpClient.interceptors().add(logging);  // <-- this is the important line!

Retrofit retrofit = new Retrofit.Builder()  
   .baseUrl(API_BASE_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(httpClient)
   .build();

これは、 HttpLoggingInterceptorを使用してロギング メソッドを追加する方法です。また、あなたが上記の本の読者であれば、Retrofit 2.0 にはもう log メソッドがないと書かれていることに気付くかもしれません -- 私が著者に尋ねたところ、これは正しくなく、彼らは来年この本を更新する予定です。それについて。

// Retrofit の Log メソッドにあまり詳しくない方のために、もう少し共有したいと思います。

また、選択できるログ レベルがいくつかあることに注意してください。ほとんどの場合、 Level.BODYを使用します。これにより、次のような結果が得られます。

ここに画像の説明を入力

ヘッダー、コンテンツ、レスポンスなど、ほぼすべての http スタッフが画像内に表示されます。

また、すべてのゲストがパーティーに参加する必要がない場合もあります。接続に成功したかどうか、Activiy & Fragmetn 内でインターネット通話が正常に行われたかどうかを知りたいだけです。次に、次のようなものを返すLevel.BASICを自由に使用できます。

ここに画像の説明を入力

内部にステータスコード200 OKが表示されていますか? それだ :)

また、ネットワークのヘッダーのみを返すLevel.HEADERSもあります。もちろん、ここに別の写真があります:

ここに画像の説明を入力

ロギングのトリックはこれですべてです ;)

そして、そこで多くのことを学んだチュートリアルを共有したいと思います。彼らは、Retrofit に関連するほぼすべてのことについて話している素晴らしい投稿をたくさん持っており、Retrofit 2.0 が来ると同時に、投稿を更新し続けています。時間を大幅に節約できると思いますので、これらの作業をご覧ください。

于 2015-12-12T06:25:11.790 に答える
15

これは、リクエストボディとレスポンスボディの両方をログに記録するInterceptorものです(OkHttpドキュメントの例と他のSOの回答に基づいて、Timberを使用しています):

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

        long t1 = System.nanoTime();
        Timber.i("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers());
        Timber.v("REQUEST BODY BEGIN\n%s\nREQUEST BODY END", bodyToString(request));

        Response response = chain.proceed(request);

        ResponseBody responseBody = response.body();
        String responseBodyString = response.body().string();

        // now we have extracted the response body but in the process
        // we have consumed the original reponse and can't read it again
        // so we need to build a new one to return from this method

        Response newResponse = response.newBuilder().body(ResponseBody.create(responseBody.contentType(), responseBodyString.getBytes())).build();

        long t2 = System.nanoTime();
        Timber.i("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers());
        Timber.v("RESPONSE BODY BEGIN:\n%s\nRESPONSE BODY END", responseBodyString);

        return newResponse;
    }

    private static String bodyToString(final Request request){

        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }
}
于 2015-09-26T19:12:22.690 に答える
8

私が直面した主な問題は、ヘッダーを動的に追加し、それらを debug logcat に記録することでした。2 つのインターセプターを追加しようとしました。1 つはロギング用、もう 1 つは外出先でヘッダーを追加するため (トークン認証)。問題は、.addInterceptor または .addNetworkInterceptor を使用できることでした。Jake Wharton が私に言ったように、「ネットワーク インターセプターは常にアプリケーション インターセプターの後に来る。https://github.com/square/okhttp/wiki/Interceptorsを参照」。したがって、ヘッダーとログを使用した実際の例は次のとおりです。

OkHttpClient httpClient = new OkHttpClient.Builder()
            //here we can add Interceptor for dynamical adding headers
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request().newBuilder().addHeader("test", "test").build();
                    return chain.proceed(request);
                }
            })
            //here we adding Interceptor for full level logging
            .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build();

    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(httpClient)
            .baseUrl(AppConstants.SERVER_ADDRESS)
            .build();
于 2016-04-25T17:17:24.473 に答える
7

これを試して:

Request request = chain.request();
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();

この後、body興味のある JSON があります。

于 2015-09-17T14:33:36.433 に答える
7

setLevel()次のように、HttpLoggingInterceptorのインスタンスでメソッドを呼び出そうとしたときに、メソッドが来ていないのと同じような状況に陥っていました。

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

Retrofit2のログを生成するために、私がそれを解決した方法は次のとおりです。

依存関係を追加したと思いますが、

implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"

チェックアウトできる最新バージョンについては、次のリンクをご覧ください。

https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor )

ここでは、追加方法についても説明しています。

name のクラスを作成しました。これAddLoggingInterceptorが私のコードです。

public class AddLoggingInterceptor {

    public static OkHttpClient setLogging(){
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build();

        return okHttpClient;
    }
}

次に、Retrofit をインスタンス化しているところで、

 public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(AddLoggingInterceptor.setLogging()) // here the method is called inside client() method, with the name of class, since it is a static method.
                .build();
    }
    return retrofit;
}

okHttpこれで、Android Studio で生成されたログを確認できます。フィルタリング プロセスを検索する必要がある場合があります。それは私のために働いた。何か問題があれば、ここにテキストを送ってください。

于 2020-05-24T14:56:37.180 に答える
5

setLogLevel() が Retrofit の最終バージョン 2.0 で返されるかどうかはわかりませんが、今のところ、ロギングにインターセプターを使用できます。

良い例は OkHttp wiki にあります: https://github.com/square/okhttp/wiki/Interceptors

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.yourjsonapi.com")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();
于 2015-09-16T00:29:20.890 に答える
2

Facebook の Stetho を追加して、Chrome でネットワーク トレースを確認することもできます: http://facebook.github.io/stetho/

final OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
    builder.networkInterceptors().add(new StethoInterceptor());
}

次に、Chromeで「chrome://inspect」を開きます...

于 2016-07-20T19:26:57.620 に答える
2

Retrofit 2.0.2 の場合、コードは次のようになります

   **HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient=new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);**


        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    **.client(httpClient.build())**
                    .build();
        }
于 2017-11-13T07:48:29.133 に答える
0

java.lang.ClassNotFoundExceptionダガー付きの場合

私は削除しました

implementation("com.squareup.okhttp3:okhttp:4.9.0")

そしてすべてが機能します。

于 2021-03-02T13:11:47.937 に答える