我试图获得在请求中发送的确切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

我应该如何做正确的日志记录,给定的删除setLog()和setLogLevel(),我们用来使用的Retrofit 1?


当前回答

当你和我试图问《Retrofit:爱在Android上使用api》一书的作者时,我遇到了这个问题(这里是链接)。 (不!)我不会为他们做广告....但他们真的是好人:) 作者很快就回复了我,在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中没有日志方法了——我问过作者,这是不正确的,他们明年会更新这本书来讨论这个问题。

//如果你不太熟悉Retrofit中的Log方法,我想分享更多的东西。

还应该注意,您可以选择一些日志级别。我使用关卡。BODY,它会给出这样的东西:

你可以在图片中找到几乎所有的http人员:头,内容和响应,等等。

有时候你真的不需要所有的客人都来参加你的派对:我只想知道它是否成功连接,在我的activity & Fragmetn中是否成功拨打互联网电话。然后你就可以自由使用Level了。BASIC,它将返回类似这样的东西:

你能找到里面的状态码200 OK吗?就是这样:)

还有一个,Level。HEADERS,它只返回网络的头信息。当然,这是另一张图:

这就是所有的日志技巧;)

我想和你们分享我在那里学到了很多的教程。他们有一堆很棒的帖子,谈论几乎所有与改造有关的事情,他们还在继续更新帖子,与此同时,改造2.0即将到来。请看一下这些工作,我想这会节省你很多时间。

其他回答

我找到了打印登录改造的方法

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (BuildConfig.DEBUG) {
                        Log.e(getClass().getName(), request.method() + " " + request.url());
                        Log.e(getClass().getName(), "" + request.header("Cookie"));
                        RequestBody rb = request.body();
                        Buffer buffer = new Buffer();
                        if (rb != null)
                            rb.writeTo(buffer);
                        LogUtils.LOGE(getClass().getName(), "Payload- " + buffer.readUtf8());
                    }
                    return chain.proceed(request);
                }
            })
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();

            iServices = new Retrofit.Builder()
                    .baseUrl("Your Base URL")
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(Your Service Interface .class);

对我有用。

当你和我试图问《Retrofit:爱在Android上使用api》一书的作者时,我遇到了这个问题(这里是链接)。 (不!)我不会为他们做广告....但他们真的是好人:) 作者很快就回复了我,在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中没有日志方法了——我问过作者,这是不正确的,他们明年会更新这本书来讨论这个问题。

//如果你不太熟悉Retrofit中的Log方法,我想分享更多的东西。

还应该注意,您可以选择一些日志级别。我使用关卡。BODY,它会给出这样的东西:

你可以在图片中找到几乎所有的http人员:头,内容和响应,等等。

有时候你真的不需要所有的客人都来参加你的派对:我只想知道它是否成功连接,在我的activity & Fragmetn中是否成功拨打互联网电话。然后你就可以自由使用Level了。BASIC,它将返回类似这样的东西:

你能找到里面的状态码200 OK吗?就是这样:)

还有一个,Level。HEADERS,它只返回网络的头信息。当然,这是另一张图:

这就是所有的日志技巧;)

我想和你们分享我在那里学到了很多的教程。他们有一堆很棒的帖子,谈论几乎所有与改造有关的事情,他们还在继续更新帖子,与此同时,改造2.0即将到来。请看一下这些工作,我想这会节省你很多时间。

嘿,伙计们,我已经找到解决方案了:

  public static <T> T createApi(Context context, Class<T> clazz, String host, boolean debug) {
    if (singleton == null) {
        synchronized (RetrofitUtils.class) {
            if (singleton == null) {
                RestAdapter.Builder builder = new RestAdapter.Builder();
                builder
                        .setEndpoint(host)
                        .setClient(new OkClient(OkHttpUtils.getInstance(context)))
                        .setRequestInterceptor(RequestIntercepts.newInstance())
                        .setConverter(new GsonConverter(GsonUtils.newInstance()))
                        .setErrorHandler(new ErrorHandlers())
                        .setLogLevel(debug ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)/*LogLevel.BASIC will cause response.getBody().in() close*/
                        .setLog(new RestAdapter.Log() {
                            @Override
                            public void log(String message) {
                                if (message.startsWith("{") || message.startsWith("["))
                                    Logger.json(message);
                                else {
                                    Logger.i(message);
                                }
                            }
                        });
                singleton = builder.build();
            }
        }
    }
    return singleton.create(clazz);
}

我也陷入了类似的情况,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)

这里他们也解释了如何添加。

我创建了一个名为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;
}

现在你可以看到日志生成在你的Android工作室,你可能需要搜索,okHttp过滤过程。这对我很管用。如果有任何问题,你可以给我发短信。

下面是一个拦截器,它同时记录请求和响应体(使用Timber,基于OkHttp文档中的一个例子和其他一些SO答案):

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