改造 2.0 如何打印完整的 json 响应?
Posted
技术标签:
【中文标题】改造 2.0 如何打印完整的 json 响应?【英文标题】:retrofit 2.0 how to print the full json response? 【发布时间】:2016-01-03 02:58:57 【问题描述】:我正在从 Volley 迁移到当前版本 2.0 的 Retrofit。
如何打印完整的json响应码?
包括:
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
RestClient:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor()
@Override
public Response intercept(Interceptor.Chain chain) throws IOException
Response response = chain.proceed(chain.request());
return response;
);
Gson gson = new GsonBuilder()
.setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ROOT)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
REST_CLIENT = retrofit.create(APIService.class);
APIService:
@GET("my/json")
Call<Model> getFeed();
在活动中 - 调用 API:
Call<Model> call = RestClient.get().getFeed();
call.enqueue(new Callback<Model>()
@Override
public void onResponse(Response<Model> response, Retrofit retrofit)
Log.w("2.0 getFeed > response.raw() => ", response.raw().toString());//DONT WORK
Log.w("2.0 getFeed > retrofit => ", retrofit.toString());//DONT WORK
Log.w("2.0 getFeed > body => ", response.body().toString()); //DONT WORK
Log.w("2.0 getFeed > getStatus => ", response.body().getStatus());
@Override
public void onFailure(Throwable t)
t.printStackTrace();
Log.e("2.0 getFeed > onFailure => ", t.toString());
);
【问题讨论】:
你只尝试过 response.body() 吗? @RajeshJadav 是的。不工作。 什么是模型??是自定义 POJO 类还是其他类? 【参考方案1】:以 json 格式打印完整响应:
Log.w("2.0 getFeed > Full json res wrapped in gson => ",new Gson().toJson(response));
如果您想要漂亮的打印功能,请使用:
Log.w("2.0 getFeed > Full json res wrapped in pretty printed gson => ",new GsonBuilder().setPrettyPrinting().create().toJson(response));
请注意,这会打印反序列化的数据(不是从服务器返回的原始响应)。要获得原始响应,您可以使用以下方法之一:
-
使用
HttpLoggingInterceptor
请参阅:https://***.com/a/33256827/2267723 或拥有自己的拦截器版本
使用Stetho
等http调试工具。请参阅:http://facebook.github.io/stetho/ 或 Charles Web Debugging Proxy
。见:https://www.charlesproxy.com
【讨论】:
这不是纯粹的响应。它只是重新序列化已经从响应中脱轨的内容并打印出来。不一样。 @HoJunLee,这是真的。要获得原始响应,请使用 HttpLoggingInterceptor 或覆盖它。您也可以使用 Stetho 或 charles 代理来监控 HTTP 流量。 我会提醒您不要这样做,您只是增加了额外的开销来将您的响应对象转换回 JSON 并打印它。正确的答案是使用下面答案中提到的日志拦截器。 @KipDiskin,我在评论中提到了这一点,并在回答中写了它。问题并不清楚应该得到哪种回应。 new GsonBuilder().setPrettyPrinting().create().toJson(response.body()) 使用这个。会正常工作的。【参考方案2】:其实 Square 已经为此创建了一个类,只需添加
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
而且,在改造中
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("https://yourapi.com/api/")
.build();
拦截器类在maven central中
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
您可以在 HttpLoggingInterceptor 类中设置日志记录级别。 BODY 是详细的(它将所有内容打印到正文)。更多信息请访问OkHttp github
小心!
不要忘记在生产环境中移除拦截器(或将日志记录级别更改为无)!否则人们将能够在 Log Cat 上看到您的请求和响应。
【讨论】:
这是正确答案。截至 2017 年 5 月 26 日,最新版本是 3.8.0 您可以谨慎使用三元运算符interceptor.setLevel(BuildConfig.DEBUG?HttpLoggingInterceptor.Level.BODY:HttpLoggingInterceptor.Level.NONE);【参考方案3】:像这样插入下面的拦截器类
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());
//////拦截器类
public static class LoggingInterceptor implements Interceptor
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException
Log.i("LoggingInterceptor","inside intercept callback");
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());
if(request.method().compareToIgnoreCase("post")==0)
requestLog ="\n"+requestLog+"\n"+bodyToString(request);
Log.d("TAG","request"+"\n"+requestLog);
com.squareup.okhttp.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 only"+"\n"+bodyString);
Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
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#
【讨论】:
它对我有用,谢谢。尽管如此,只需将以下部分代码Response response = chain.proceed(request); ... Log.d("TAG","response"+"\n"+resposneLog+"\n"+bodyString);
添加到您的 new Interceptor() ... 中就足够了
这对我很有用,非常适合独立记录我的应用程序逻辑之外的所有网络响应。
使用response.peekBody()
方法,无需新建ResponseBody
【参考方案4】:
在下面的改造中使用 Json 获得完整响应。
这对我有用。
call.enqueue(new Callback<someList>()
@Override
public void onResponse(Call<someList> call, Response<someList> response)
if (response.isSuccessful())
Log.e("Success", new Gson().toJson(response.body()));
else
Log.e("unSuccess", new Gson().toJson(response.errorBody()));
@Override
public void onFailure(Call<someList> call, Throwable t)
Log.e("onFailure", t.toString());
);
【讨论】:
【参考方案5】:您可以像下面这样将setLogLevel
连接到您的Retrofit
适配器,并查看响应和其他数据,例如标头、响应代码与
setLogLevel(LogLevel.FULL)
如果您使用的是 Retrofit 版本 2+,则必须设置 OkHttpLoggingInterceptor
才能查看日志。
首先将OkHttpLoggingInterceptor
添加到您的项目中:
com.squareup.okhttp3:logging-interceptor:$Versions.okHttpLoggingInterceptorVersion
然后创建你的拦截器:
HttpLoggingInterceptor().apply level = HttpLoggingInterceptor.Level.BODY
最后将它添加到你的 OkHttpClient
with(OkHttpClient.Builder())
if (BuildConfig.DEBUG) addInterceptor(loggingInterceptor)
build()
【讨论】:
你不能在 Retrofit 2.0 中添加 setLogLevel(LogLevel.FULL)【参考方案6】:试试这个!!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
/** Handles Log */
retrofit.client().interceptors().add(new LoggingInterceptor());
mRestClient = retrofit.create(RestServices.class);
class LoggingInterceptor implements Interceptor
@Override
public Response intercept(Interceptor.Chain chain) throws IOException
Request request = chain.request();
long t1 = System.nanoTime();
Logger.d(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Logger.d(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
final String responseString = new String(response.body().bytes());
Logger.d("Response: " + responseString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), responseString))
.build();
Check this Demo !!!
【讨论】:
【参考方案7】:Log.e("TAG","2.0 getFeed > response.raw() => " + new Gson().toJson(response.body()));
【讨论】:
【参考方案8】:public class HttpLoggingInterceptor
HttpLoggingInterceptor provideHttpLoggingInterceptor()
return new HttpLoggingInterceptor(message ->
Log.d("TAG", message)).setLevel(HttpLoggingInterceptor.Level.BODY);
public class OkHttpClient
OkHttpClient provideOkHttpClient(@NonNull HttpLoggingInterceptor interceptor)
return new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
【讨论】:
您应该始终在答案中添加 cmets 或描述【参考方案9】:试试这个:
Log.d("LOG","RESPONSE ==="+response.raw().toString());
【讨论】:
【参考方案10】:看看 okhttp3.logging 包,他们已经有 HttpLoggingInterceptor ,你可以使用它来满足你的需要。 根据它们,您还可以指定日志记录级别。
您可以通过 OkHttpClient.Builder 将这个拦截器包含在您的请求中:
public OkHttpClient provideOkHttpClient()
final OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
okHttpBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
return okHttpBuilder.build();
【讨论】:
【参考方案11】:要使用改造 2.0 获得完整的 json 响应,请遵循下面给出的代码
API接口
@GET("my/json")
Call<JsonObject> getFeed();
改造调用函数
Call<JsonObject> call = RestClient.get().getFeed();
call.enqueue(new Callback<JsonObject>()
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response)
Log.d("res", response.body().toString());
@Override
public void onFailure(Call<JsonObject> call, Throwable t)
Log.d("error",t.getMessage());
);
【讨论】:
【参考方案12】:Call<Model> call = RestClient.get().getFeed();call.enqueue(new Callbstrong
textack<Model>()
@Override
public void onResponse(Response<Model> response, Retrofit retrofit)
//try this
Call<Model> call = response.body();
// this is enough for retrieve model
@Override
public void onFailure(Throwable t)
t.printStackTrace();
og.e("2.0 getFeed > onFailure => ", t.toString());
);
【讨论】:
以上是关于改造 2.0 如何打印完整的 json 响应?的主要内容,如果未能解决你的问题,请参考以下文章