如何使用 Retrofit-Android 记录请求和响应主体?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21886313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to log request and response body with Retrofit-Android?
提问by Jaguar
I can't find relevant methods in the Retrofit API for logging complete request/response bodies. I was expecting some help in the Profiler (but it only offers meta-data about response). I tried setting the log level in the Builder, but this doesn't help me either :
我在 Retrofit API 中找不到用于记录完整请求/响应主体的相关方法。我期待 Profiler 中的一些帮助(但它只提供有关响应的元数据)。我尝试在 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();
EDIT: This code is working now. I don't know why it wasn't working earlier. Possibly because I was using some older version of retrofit.
编辑:此代码现在正在运行。我不知道为什么它不能早点工作。可能是因为我使用了一些旧版本的改造。
采纳答案by Alex Dzeshko
I used setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG"))
, it helped me.
UPDATE.
You can also try for debug purpose use retrofit.client.Response
as response model
我用过setLogLevel(LogLevel.FULL).setLog(new AndroidLog("YOUR_LOG_TAG"))
,对我有帮助。
更新。
您也可以尝试用于调试目的retrofit.client.Response
用作响应模型
回答by Dhaval Jivani
Retrofit 2.0:
改造 2.0:
UPDATE: @by Marcus P?hls
更新:@by Marcus P?hls
Logging In Retrofit 2
登录改造2
Retrofit 2 completely relies on OkHttp for any network operation. Since OkHttp is a peer dependency of Retrofit 2, you won't need to add an additional dependency once Retrofit 2 is released as a stable release.
Retrofit 2 完全依赖 OkHttp 进行任何网络操作。由于 OkHttp 是 Retrofit 2 的对等依赖项,因此一旦 Retrofit 2 作为稳定版本发布,您将不需要添加额外的依赖项。
OkHttp 2.6.0 ships with a logging interceptor as an internal dependency and you can directly use it for your Retrofit client. Retrofit 2.0.0-beta2 still uses OkHttp 2.5.0. Future releases will bump the dependency to higher OkHttp versions. That's why you need to manually import the logging interceptor. Add the following line to your gradle imports within your build.gradle file to fetch the logging interceptor dependency.
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'
You can also visit Square's GitHub page about this interceptor
你也可以访问 Square 的 GitHub 页面关于这个拦截器
Add Logging to Retrofit 2
将日志记录添加到改造 2
While developing your app and for debugging purposes it's nice to have a log feature integrated to show request and response information. Since logging isn't integrated by default anymore in Retrofit 2, we need to add a logging interceptor for OkHttp. Luckily OkHttp already ships with this interceptor and you only need to activate it for your OkHttpClient.
在开发您的应用程序和出于调试目的时,最好集成一个日志功能来显示请求和响应信息。由于在 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();
We recommend to add logging as the last interceptor, because this will also log the information which you added with previous interceptors to your request.
我们建议将日志记录添加为最后一个拦截器,因为这也会记录您在之前的拦截器中添加到您的请求中的信息。
Log Levels
日志级别
Logging too much information will blow up your Android monitor, that's why OkHttp's logging interceptor has four log levels: NONE, BASIC, HEADERS, BODY. We'll walk you through each of the log levels and describe their output.
记录太多信息会炸毁你的安卓显示器,这就是为什么 OkHttp 的日志拦截器有四个日志级别:NONE、BASIC、HEADERS、BODY。我们将带您了解每个日志级别并描述它们的输出。
further information please visit : Retrofit 2 — Log Requests and Responses
更多信息请访问:改造 2 — 日志请求和响应
OLD ANSWER:
旧答案:
no logging in Retrofit 2 anymore. The development team removed the logging feature. To be honest, the logging feature wasn't that reliable anyway. Jake Wharton explicitly stated that the logged messages or objects are the assumed values and they couldn't be proofed to be true. The actual request which arrives at the server may have a changed request body or something else.
不再登录 Retrofit 2。开发团队删除了日志记录功能。老实说,无论如何,日志记录功能都不是那么可靠。Hyman沃顿明确表示,记录的消息或对象是假定值,无法证明它们是真实的。到达服务器的实际请求可能具有更改的请求正文或其他内容。
Even though there is no integrated logging by default, you can leverage any Java logger and use it within a customized OkHttp interceptor.
即使默认情况下没有集成日志记录,您也可以利用任何 Java 记录器并在定制的 OkHttp 拦截器中使用它。
further information about Retrofit 2 please refer : Retrofit — Getting Started and Create an Android Client
有关 Retrofit 2 的更多信息,请参阅: Retrofit — 入门和创建 Android 客户端
回答by OWADVL
Update for Retrofit 2.0.0-beta3
Retrofit 2.0.0-beta3 的更新
Now you have to use okhttp3 with builder. Also the old interceptor will not work. This response is tailored for Android.
现在您必须将 okhttp3 与 builder 一起使用。旧的拦截器也不起作用。此响应是为 Android 量身定制的。
Here's a quick copy paste for you with the new stuff.
这是新内容的快速复制粘贴。
1. Modify your gradle file to
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. Check this sample code:
2. 检查此示例代码:
with the new imports. You can remove Rx if you don't use it, also remove what you don't use.
随着新的进口。如果您不使用 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);
}
}
}
Bonus
奖金
I know it's offtopic but I find it cool.
我知道这是题外话,但我觉得它很酷。
In case there's an http error code of unauthorized, here is an interceptor. I use eventbus for transmitting the event.
如果有一个未授权的 http 错误代码,这里是一个拦截器。我使用 eventbus 传输事件。
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;
}
}
code take from https://github.com/AndreiD/UltimateAndroidTemplateRx(my project).
代码取自https://github.com/AndreiD/UltimateAndroidTemplateRx(我的项目)。
回答by Xeridea
There doesn't appear to be a way to do basic + body, but you can use FULL and filter the headers you don't want.
似乎没有办法做基本 + 正文,但您可以使用 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();
It appears that when overriding the log, the body is prefixed with a tag similar to
似乎在覆盖日志时,正文以类似于的标签为前缀
[ 02-25 10:42:30.317 25645:26335 D/Retrofit ]
so it should be easy to log basic + body by adjusting the custom filter. I am using a blacklist, but a whitelist could also be used depending on your needs.
所以通过调整自定义过滤器应该很容易记录基本+正文。我使用的是黑名单,但也可以根据您的需要使用白名单。
回答by Mukesh Parmar
below code is working for both with header and without header to print log request & response. Note: Just comment .addHeader() line if are not using header.
下面的代码适用于有标题和没有标题的打印日志请求和响应。注意:如果不使用标题,只需注释 .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();
回答by Talha Bilal
I hope this code will help you to logging .
you just need to add interceptor in your Build.Gradle
then make RetrofitClient
.
我希望这段代码能帮助你记录。
你只需要在你的Build.Gradle
then make 中添加拦截器RetrofitClient
。
First Step
第一步
Add this line to your build.gradle
将此行添加到您的 build.gradle
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
Second Step
第二步
Make your Retrofit Client
做你的改造客户端
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;
}
}
Calling
打电话
RetrofitClient.getInstance(context).getApiService().yourRequestCall();
回答by NickUnuchek
If you are using Retrofit2 and okhttp3 then you need to know that Interceptor works by queue. So add loggingInterceptor at the end, after your other Interceptors:
如果您使用的是 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();
回答by Ibrahim AbdelGawad
ZoomX — Android Logger Interceptoris a great interceptor can help you to solve your problem.
ZoomX — Android Logger Interceptor是一个很棒的拦截器,可以帮助您解决问题。
回答by shehzy
For android studio before 3.0 (using android motinor)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M
对于 3.0 之前的 android studio(使用 android motinor)
https://futurestud.io/tutorials/retrofit-2-log-requests-and-responses
https://www.youtube.com/watch?v=vazLpzE5y9M
And for android studio from 3.0 and above (using android profiler as android monitor is replaced by android profiler)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler
对于 3.0 及以上版本的 android studio(使用 android profiler 作为 android 监视器被 android profiler 替换)
https://futurestud.io/tutorials/retrofit-2-analyze-network-traffic-with-android-studio-profiler