Registro con Retrofit 2


Estoy tratando de obtener el JSON exacto que se envía en la solicitud. Aquí está mi código:

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();

Pero solo veo esto en los registros:

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json

¿Cómo se supone que debo hacer un registro adecuado, dada la eliminación de setLog() y setLogLevel() que solíamos usar con Retrofit 1?

Author: David Cheung, 2015-09-11

15 answers

En Retrofit 2 debe usar HttpLoggingInterceptor.

Añadir dependencia a build.gradle:

compile 'com.squareup.okhttp3:logging-interceptor:3.9.1'

Crea un objeto Retrofit como el siguiente:

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);

La solución anterior le da mensajes logcat muy similares a los antiguos establecidos por

setLogLevel(RestAdapter.LogLevel.FULL)

En caso de java.lang.ClassNotFoundException:

Una versión más antigua puede requerir una versión más antigua de logging-interceptor. Echa un vistazo a las secciones de comentarios para más detalles.

 529
Author: klimat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-04 11:12:57

Me encontré con la cosa como usted y yo tratamos de preguntar al autor del libro Retrofit: Me encanta trabajar con API en Android (aquí está el enlace ) (¡no! No estoy haciendo algunos anuncios para ellos....pero son muy buenos chicos :) Y el autor me respondió muy pronto, con ambos método de registro en Retrofit 1.9 y Retrofit 2.0-beta.

Y aquí está el código de 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();

Así es como se agrega el método de registro con la ayuda de HttpLoggingInterceptor. También si usted es el lector de ese libro que mencioné anteriormente, puede encontrar que dice que no hay método de registro con Retrofit 2.0 más which que, le había preguntado al autor, no es correcto y actualizarán el libro el próximo año hablando de ello.

// En caso de que no esté familiarizado con el método de Registro en Retrofit, me gustaría compartir algo más.

También debe tenerse en cuenta que hay algunos niveles de registro que puede elegir. Utilizo el nivel .CUERPO la mayor parte del tiempo, lo que dará algo como esto:

introduzca la descripción de la imagen aquí

Puede encontrar casi todo el pentagrama http dentro de la imagen: el encabezado, el contenido y la respuesta, etc.

Y a veces realmente no necesitas que todos los invitados asistan a tu fiesta: solo quiero saber si está conectada con éxito, esa llamada por Internet se realiza con éxito dentro de mi Activiy & Fragmetn. Entonces usted es libre de usar el nivel .BASIC, que devolverá algo como esto:

introduzca la descripción de la imagen aquí

¿Puedes encontrar el código de estado 200 OK dentro? Eso es todo :)

También hay otro nivel, .HEADERS , que solo devolverá la cabecera de la red. Ya por supuesto otra imagen aquí:

introduzca la descripción de la imagen aquí

Eso es todo el truco de registro;)

Y me gustaría compartirte con el tutorial que aprendí mucho allí. Tienen un montón de grandes post hablando de casi todo relacionado con Retrofit, y continúan actualizando el post, al mismo tiempo que Retrofit 2.0 está llegando. Por favor, eche un vistazo a esos trabajos, lo que creo que le ahorrará mucho tiempo.

 27
Author: Anthonyeef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-12 06:25:11

Aquí hay un Interceptor que registra tanto los cuerpos de solicitud como de respuesta (utilizando Timber, basado en un ejemplo de los documentos OkHttp y algunas otras respuestas 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";
        }
    }
}
 9
Author: david.mihola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-26 19:12:22

Prueba esto:

Request request = chain.request();
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();

Después de esto, en el body está el JSON que le interesa.

 5
Author: Anton Ryabyh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-05 20:16:26

No se si setLogLevel() regresará en la versión 2.0 final de Retrofit pero por ahora puedes usar un interceptor para el registro.

Un buen ejemplo se puede encontrar en 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();
 4
Author: oceanfeeling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 00:29:20

Para aquellos que necesitan un registro de alto nivel en Retrofit, use el interceptor como este

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";
    }
}`

Cortesía: https://github.com/square/retrofit/issues/1072#

 4
Author: DGN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-22 07:12:52

El principal problema al que me enfrenté fue la adición dinámica de encabezados y su registro en debug logcat. He intentado añadir dos interceptores. Uno para el registro y otro para agregar encabezados sobre la marcha (autorización de token). El problema era que podríamos .addInterceptor o .addNetworkInterceptor. Como Jake Wharton me dijo: "Los interceptores de red siempre vienen después de los interceptores de aplicaciones. Véase https://github.com/square/okhttp/wiki/Interceptors". Así que aquí está el ejemplo de trabajo con encabezados y registros:

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();
 4
Author: Yazon2006,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-15 19:56:00

Si está utilizando Retrofit2 y okhttp3, entonces necesita saber que Interceptor funciona por cola. Así que agrega loggingInterceptor al final, después de tus otros interceptores:

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();
 4
Author: NickUnuchek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-20 08:44:20

También puede agregar Stetho de Facebook y mirar los rastros de red en Chrome: http://facebook.github.io/stetho /

final OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
    builder.networkInterceptors().add(new StethoInterceptor());
}

A continuación, abra "chrome://inspect" en Chrome...

 2
Author: kenyee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-20 19:26:57

Una mejor manera de hacer esto bien en Retrofit 2 es agregar el interceptor del registrador como un networkInterceptor esto imprimirá los encabezados de red y sus encabezados personalizados también. Lo importante es recordar que el interceptor funciona como una pila y asegúrese de agregar el registrador al final de todo.

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());
 1
Author: Catluc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-03 15:24:16

La mayor parte de la respuesta aquí cubre casi todo excepto esta herramienta, una de las mejores formas de ver el registro.

Es La Estetho de Facebook. Esta es la excelente herramienta para monitorear/registrar el tráfico de red de su aplicación en google chrome. También puedes encontrar aquí en Github.

introduzca la descripción de la imagen aquí

 1
Author: Nishant Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-09 09:36:13

He encontrado la manera de Imprimir Inicio de sesión en Retrofit

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (BuildConfig.DEBUG) {
                        Log.e(getClass().getName(), request.method() + " " + request.url());
                        Log.e(getClass().getName(), "" + request.header("Cookie"));
                        RequestBody rb = request.body();
                        Buffer buffer = new Buffer();
                        if (rb != null)
                            rb.writeTo(buffer);
                        LogUtils.LOGE(getClass().getName(), "Payload- " + buffer.readUtf8());
                    }
                    return chain.proceed(request);
                }
            })
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();

            iServices = new Retrofit.Builder()
                    .baseUrl("Your Base URL")
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(Your Service Interface .class);

Funciona para mí.

 0
Author: Nilesh Senta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-28 04:58:19

Para Retrofit 2.0.2 el código es como

   **HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient=new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);**


        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    **.client(httpClient.build())**
                    .build();
        }
 0
Author: Paul Mathew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-15 05:10:46

Código Kotlin

        val interceptor = HttpLoggingInterceptor()
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
        val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
        val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        return retrofit.create(PointApi::class.java)
 0
Author: Jorge Casariego,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-28 19:13:02

Hey chicos,ya encuentro la solución:

  public static <T> T createApi(Context context, Class<T> clazz, String host, boolean debug) {
    if (singleton == null) {
        synchronized (RetrofitUtils.class) {
            if (singleton == null) {
                RestAdapter.Builder builder = new RestAdapter.Builder();
                builder
                        .setEndpoint(host)
                        .setClient(new OkClient(OkHttpUtils.getInstance(context)))
                        .setRequestInterceptor(RequestIntercepts.newInstance())
                        .setConverter(new GsonConverter(GsonUtils.newInstance()))
                        .setErrorHandler(new ErrorHandlers())
                        .setLogLevel(debug ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)/*LogLevel.BASIC will cause response.getBody().in() close*/
                        .setLog(new RestAdapter.Log() {
                            @Override
                            public void log(String message) {
                                if (message.startsWith("{") || message.startsWith("["))
                                    Logger.json(message);
                                else {
                                    Logger.i(message);
                                }
                            }
                        });
                singleton = builder.build();
            }
        }
    }
    return singleton.create(clazz);
}
 -11
Author: Vihuela Yao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-24 07:06:03