tutorial example java retrofit retrofit2 okhttp3

java - tutorial - retrofit login example



Inicio de sesiĆ³n con Retrofit 2 (18)

Aquí hay un Interceptor que registra los cuerpos de solicitud y respuesta (usando 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"; } } }

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?


Aquí hay una manera simple de filtrar cualquier parámetro de solicitud / respuesta de los registros utilizando HttpLoggingInterceptor :

// Request patterns to filter private static final String[] REQUEST_PATTERNS = { "Content-Type", }; // Response patterns to filter private static final String[] RESPONSE_PATTERNS = {"Server", "server", "X-Powered-By", "Set-Cookie", "Expires", "Cache-Control", "Pragma", "Content-Length", "access-control-allow-origin"}; // Log requests and response HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { // Blacklist the elements not required for (String pattern: REQUEST_PATTERNS) { if (message.startsWith(pattern)) { return; } } // Any response patterns as well... for (String pattern: RESPONSE_PATTERNS) { if (message.startsWith(pattern)) { return; } } Log.d("RETROFIT", message); } }); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

Aquí está la esencia completa:

https://gist.github.com/mankum93/179c2d5378f27e95742c3f2434de7168


Conocí la cosa como tú y traté de preguntarle al autor del libro Retrofit: Me encanta trabajar con API en Android (aquí está el link ) (¡no! No estoy haciendo algunos anuncios para ellos ... pero son realmente agradables chicos :) Y el autor me respondió muy pronto, con el método Log 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 . Además, si usted es el lector de ese libro que mencioné anteriormente, puede encontrar que dice que ya no hay un método de registro con Retrofit 2.0, que, le pregunté al autor, no es correcto y actualizarán el libro el próximo año hablando al respecto

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

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

Puede encontrar casi todo el personal de 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á conectado correctamente, esa llamada de Internet se realizó con éxito dentro de mi Activiy & Fragmetn. Entonces puedes usar Level.BASIC , que devolverá algo como esto:

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

También hay otro, Level.HEADERS , que solo devolverá el encabezado de la red. Ya, por supuesto, otra foto aquí:

Ese es todo el truco de registro;)

Y me gustaría compartirlo con el tutorial que aprendí mucho there . Tienen un montón de excelentes publicaciones que hablan sobre casi todo lo relacionado con Retrofit, y continúan actualizando la publicación, al mismo tiempo que viene Retrofit 2.0. Eche un vistazo a esos trabajos, que creo que le ahorrarán mucho tiempo.


El principal problema al que me enfrenté fue agregar dinámicamente encabezados y registrarlos en debug logcat. Intenté agregar dos interceptores. Uno para iniciar sesión y otro para agregar encabezados sobre la marcha (autorización de token). El problema es que podemos .addInterceptor o .addNetworkInterceptor. Como Jake Wharton me dijo: "Los interceptores de red siempre vienen después de los interceptores de aplicación. Ver https://github.com/square/okhttp/wiki/Interceptors ". Así que aquí hay un ejemplo de trabajo con encabezados y registros:

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


En Retrofit 2 debe usar HttpLoggingInterceptor .

Agregue dependencia a build.gradle :

implementation ''com.squareup.okhttp3:logging-interceptor:3.12.1''

Cree 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 brinda mensajes logcat muy similares a los antiguos establecidos por

setLogLevel(RestAdapter.LogLevel.FULL)

En caso de java.lang.ClassNotFoundException :

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


Encontré el camino para Imprimir Iniciar sesión 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 mi.


Esto creará un objeto de actualización con Logging. sin crear objetos separados.

private static final Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(new OkHttpClient().newBuilder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS) .writeTimeout(WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS) .connectTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS) .build()) .addConverterFactory(GsonConverterFactory.create()) .build();


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


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

Es http://facebook.github.io/stetho/ . Esta es la excelente herramienta para monitorear / registrar el tráfico de red de su aplicación en Google Chrome . También puedes encontrarlo here en Github.


No sé si setLogLevel () volverá en la versión 2.0 final de Retrofit, pero por ahora puede usar un interceptor para iniciar sesión.

Un buen ejemplo se puede encontrar en OkHttp wiki: https://github.com/square/okhttp/wiki/Interceptors

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


Para aquellos que necesitan un registro de alto nivel en Retrofit, use el interceptor de esta manera

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

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


Primero agregue dependencia a build.gradle:

implementación ''com.squareup.okhttp3: logging-interceptor: 3.12.1''

Mientras usa Kotlin, puede agregar Logging Interceptor de esta manera:

companion object { val okHttpClient = OkHttpClient().newBuilder() .addInterceptor(HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }) .build() fun getRetrofitInstance(): Retrofit { val retrofit = Retrofit.Builder() .client(okHttpClient) .baseUrl(ScanNShopConstants.BASE_URL) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() return retrofit } }


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.


Si está utilizando Retrofit2 y okhttp3, entonces necesita saber que Interceptor funciona en cola. Entonces agregue loggingInterceptor al final, después de sus 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();


También puede agregar Stetho de Facebook y ver 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()); }

Luego abra "chrome: // inspeccionar" en Chrome ...


Una mejor manera de hacer esto correctamente en Retrofit 2 es agregar el interceptor de registrador como un interceptor de red, esto también imprimirá los encabezados de red y sus encabezados personalizados. 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());


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


Código Kotlin

val interceptor = HttpLoggingInterceptor() interceptor.level = 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)