使用Retrofit 2进行记录

Gab*_*bor 287 java retrofit retrofit2 okhttp3

我正在尝试获取请求中发送的确切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();
Run Code Online (Sandbox Code Playgroud)

但我只在日志中看到这个:

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json
Run Code Online (Sandbox Code Playgroud)

我怎么做正确的记录,考虑到拆除setLog()setLogLevel()我们使用了改造1使用哪个?

kli*_*mat 652

在Retrofit 2中你应该使用HttpLoggingInterceptor.

添加依赖项build.gradle:

implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'
Run Code Online (Sandbox Code Playgroud)

创建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);
Run Code Online (Sandbox Code Playgroud)

上面的解决方案为您提供了非常类似于旧设置的logcat消息

interceptor.level(HttpLoggingInterceptor.Level.BODY);
Run Code Online (Sandbox Code Playgroud)

在以下情况下setLevel:

较旧的Retrofit版本可能需要较旧的java.lang.ClassNotFoundException版本.有关详细信息,请查看注释部分.

  • 在我提出问题后的15天内,这已被添加到OkHttp中,很好的社区需要如此快速的影响! (27认同)
  • 改造2.1.0使用这个编译'com.squareup.okhttp3:logging-interceptor:3.3.1' (13认同)
  • @jayellos感谢您表示.如果使用版本低于3.3.1的版本,则不会出现此类方法异常. (2认同)
  • 我得到:没有找到类"okhttp3.internal.Platform"的任何想法? (2认同)

Ant*_*eef 31

我和你见过这件事,我试着问一下这本书的作者Retrofit:爱在Android上使用API(这里是链接)(不是!我不是为他们制作一些广告......但他们真的很好伙计们:)作者很快回复了我,使用Retrofit 1.9上的Log方法和Retrofit 2.0-beta.

以下是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();
Run Code Online (Sandbox Code Playgroud)

这是在HttpLoggingInterceptor的帮助下添加日志记录方法的方法.另外,如果你是我上面提到的那本书的读者,你可能会发现它说再没有使用Retrofit 2.0的日志方法了 - 我曾经问过作者,这是不正确的,明年他们会更新这本书关于它.

//如果您不熟悉Retrofit中的Log方法,我想分享更多内容.

还应注意,您可以选择一些日志级别.我大部分时间都使用Level.BODY,它会给出一些这样的东西:

在此输入图像描述

您可以在图片中找到几乎所有的http人员:标题,内容和响应等.

有时你真的不需要所有的客人参加你的派对:我只是想知道它是否成功连接,在我的Activiy&Fragmetn中成功进行了互联网通话.然后你可以自由使用Level.BASIC,它将返回如下内容:

在此输入图像描述

你能在里面找到状态码200 OK吗?这就对了 :)

还有另一个,Level.HEADERS,它只返回网络的标题.雅当然另一张图片在这里:

在此输入图像描述

这就是所有的记录技巧;)

我想与大家分享我在那里学到的很多东西.他们有很多很棒的帖子谈论与Retrofit相关的几乎所有内容,他们正在继续更新帖子,同时Retrofit 2.0即将推出.请看一下这些工作,我认为这将为您节省大量时间.

  • 此外,这对我不起作用.httpClient.interceptors.add想要一个com.squareup.okhttp.Interceptor而不是一个okhttp3.logging.HttpLoggingInterceptor (5认同)

dav*_*ola 10

这是一个Interceptor记录请求和响应主体(使用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";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ant*_*byh 6

试试这个:

Request request = chain.request();
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();
Run Code Online (Sandbox Code Playgroud)

在此之后,body您会感兴趣的是JSON.

  • @GilbertoIbarra使用`String bodyString = response.body().string(); 日志(bodyString); response = response.newBuilder().body(ResponseBody.create(response.body().contentType(),bodyString)).build(); `(您不能多次读取响应的主体,因此您必须使用构建器创建新的响应) (3认同)

Yaz*_*006 6

我面临的主要问题是动态添加标头并将它们记录到调试logcat中。我尝试添加两个拦截器。一种用于记录日志,另一种用于在运行时添加标头(令牌授权)。问题在于我们可能使用.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();
Run Code Online (Sandbox Code Playgroud)


Nic*_*hek 6

如果您使用的是 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))//first
                .addInterceptor(new OAuthInterceptor(context))//second
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//third, log at the end
                .build();
Run Code Online (Sandbox Code Playgroud)


oce*_*ing 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();
Run Code Online (Sandbox Code Playgroud)


Jwa*_*mar 5

我也陷入了类似的情况,setLevel()方法没有来,当我试图用 HttpLoggingInterceptor 的实例调用它时,像这样:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
Run Code Online (Sandbox Code Playgroud)

这是我解决它的方法,为 Retrofit2 生成日志,

我想你已经添加了依赖,

implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
Run Code Online (Sandbox Code Playgroud)

如需最新版本,您可以查看此链接:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在我们实例化我们的改造的地方,

 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;
}
Run Code Online (Sandbox Code Playgroud)

现在你可以看到在你的 Android Studio 中生成的日志,你可能需要搜索,okHttp过滤过程。它对我有用。如果有任何问题,您可以在这里给我发短信。