我试图获得在请求中发送的确切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 2中做到这一点的最好方法是添加记录器拦截器作为networkInterceptor,这将打印出网络头和您的自定义头。重要的是要记住,拦截器作为一个堆栈工作,并确保在所有的末尾添加记录器。
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new MyCustomInterceptor());
builder.connectTimeout(60, TimeUnit.SECONDS);
builder.readTimeout(60, TimeUnit.SECONDS);
builder.writeTimeout(60, TimeUnit.SECONDS);
// important line here
builder.addNetworkInterceptor(LoggerInterceptor());
对于那些需要在Retrofit中进行高级日志记录的人,可以像这样使用拦截器
public static class LoggingInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
String requestLog = String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers());
//YLog.d(String.format("Sending request %s on %s%n%s",
// request.url(), chain.connection(), request.headers()));
if(request.method().compareToIgnoreCase("post")==0){
requestLog ="\n"+requestLog+"\n"+bodyToString(request);
}
Log.d("TAG","request"+"\n"+requestLog);
Response response = chain.proceed(request);
long t2 = System.nanoTime();
String responseLog = String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
String bodyString = response.body().string();
Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
//return response;
}
}
public 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";
}
}`
礼貌:https://github.com/square/retrofit/issues/1072
我也陷入了类似的情况,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过滤过程。这对我很管用。如果有任何问题,你可以给我发短信。
如果您正在使用Retrofit2和okhttp3,那么您需要知道Interceptor是通过队列工作的。所以在你的其他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();
下面是一个拦截器,它同时记录请求和响应体(使用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";
}
}
}