【问题标题】:retrofit 2.0 how to print the full json response?改造 2.0 如何打印完整的 json 响应?
【发布时间】: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 类还是其他类?

标签: java android http android-activity retrofit


【解决方案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));

请注意,这会打印反序列化的数据(不是从服务器返回的原始响应)。要获得原始响应,您可以使用以下方法之一:

  1. 使用HttpLoggingInterceptor 请参阅:https://stackoverflow.com/a/33256827/2267723 或拥有自己的拦截器版本
  2. 使用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());
              
              }
              
              });
              

              【讨论】:

                猜你喜欢
                • 2014-11-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-02-25
                • 1970-01-01
                • 2019-03-14
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多