Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK
Code

Enviando Datos Con el Cliente HTTP Retrofit 2 para Android

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by Rafael Chavarría (you can also view the original English article)

Final product image
What You'll Be Creating

¿Qué Es Retrofit?

Retrofit es un cliente HTTP de tipo seguro para Android y Java. Retrofit hace sencillo conectar a un servicio web REST traduciendo la API a interfaces Java. En este tutorial, te mostraré cómo usar una de las librerías HTTP más populares y frecuentemente recomendada disponible para Android.

Esta poderosa librería hace sencillo consumir datos JSON o XML, que después es analizado en Objetos Java (Plain Old Java Objects, POJOs). Todas las peticiones GETPOSTPUTPATCH, and DELETE pueden ser ejecutadas.

Como la mayoría del software de código abierto, Retrofit fue construido encima de algunas otras librerías y herramientas poderosas. Tras bambalinas, Retrofit hace uso de OkHttp (del mismo desarrollador) para manejar peticiones de red. También, Retrofit no tiene un convertidor JSON integrado para convertir de objetos JSON a Java. En su lugar, viene con soporte para las siguientes librerías de convertidor JSON para manejar eso:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi

Para buffers de Protocolo, Retrofit soporta:

  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire

Y para XML Retrofit soporta:

  • Simple Framework: com.squareup.retrofit2:converter-simpleframework

¿Así Qué Por Qué Usar Retrofit?

Desarrollar tu propia librería HTTP de tipo seguro para hacer interfaz con una API REST puede ser bastante tedioso: tienes que manejar muchos aspectos, tales como hacer conexiones, cachear, reintentar peticiones fallidas, hilación, análisis de respuesta, manejo de errores, y más. Retrofit, por otro lado, es una librería bien planeada, documentada y probada que te ahorrará mucho tiempo valioso y dolores de cabeza.

En este tutorial explicaré cómo usar Retrofit 2 para manejar peticiones de red construyendo una aplicación simple que realizará peticiones POST, peticiones PUT (para actualizar entidades), y peticiones DELETE. También te mostraré cómo integrar con RxJava y cómo cancelar peticiones. Estaremos usando la API provista por JSONPlaceholder---esta es una API REST falsa en línea para pruebas y prototipado.

Revisa mi tutorial anterior, Comenzando Con el Cliente HTTP Retrofit 2, para aprender cómo ejecutar peticiones GET y cómo integrar Retrofit con RxJava.

1. Crea un Proyecto Android Studio

Inicia Android Studio y crea un nuevo proyecto con una actividad vacía llamada MainActivity.

create a new empty activity

2. Declarando Dependencias

Después de crear un nuevo proyecto, declara las siguientes dependencias en tu build.gradle. Las dependencias incluyen la librería Retrofit y también la librería Gson de Google para convertir JSON a POJO (Plan Old Java Objects) así como la integración Gson de Retrofit.

Asegúrate de sincronizar tu proyecto después de agregar las dependencias.

3. Agregando el Permiso de Internet

Para realizar operaciones de red, necesitamos incluir el permiso INTERNET en el manifest de la aplicación: AndroidManifest.xml.

4. Generando Modelos Automáticamente

Vamos a crear modelos automáticamente desde la información de respuesta JSON  aprovechando una herramienta bastante útil: jsonschema2pojo. Nos gustaría hacer una petición POST (crear un nuevo recurso) sobre la API. Pero antes de ejecutar esta petición, necesitamos saber la respuesta JSON que deberíamos esperar cuando se ejecuta exitosamente para que Retrofit pueda analizar la respuesta JSON y deserializarla a objetos Java. De acuerdo a la API, si enviamos los siguientes datos en una petición POST:

Deberíamos obtener la siguiente respuesta:

Mapea los Datos JSON a Java

Copia los datos de respuesta de muestra de la sección anterior. Ahora visita jsonschema2pojo y pega la respuesta JSON en la caja de entrada. Selecciona el tipo de fuente de JSON, estilo de anotación de Gson, y desmarca Permitir propiedades adicionales, y cambia el nombre de la clase de Ejemplo a Post.

jsonschema2pojo input

Después da clic al botón Vista Previa para generar los objetos Java.

jsonschema2pojo output

¡Podrías estarte preguntando lo que hacen las anotaciones @SerializedName y @Expose en este código generado! ¡No te preocupes, lo explicaré todo!

La anotación @SerializedName es necesaria para que Gson mapee las llaves JSON a campos de objeto Java.

En este caso, la llave JSON userId es mapeada al campo de clase userId. Pero nota que ya que son el mismo, no hay necesidad de incluir la anotación @SerializedName en el campo porque Gson los mapeará automáticamente por nosotros.

La anotación @Expose indica que el miembro de la clase debería ser expuesto para serialización o deserialización JSON.

Importa Modelos de Datos a Android Studio

Ahora regresemos a Android Studio. Crea un nuevo sub-paquete dentro del paquete main y llámalo data. Dentro del recién creado paquete, crea otro paquete y llámalo model. Dentro de este paquete, crea una nueva clase Java y llámala Post. Ahora copia la clase Post que fue generada por jsonschema2pojo y pégala dentro de la clase Post que creaste.

Además de los getters y setters, también incluí el método toString(). (En Intellij, puedes usar el comando Generate para hacer esto fácil: Alt-Insertar en Windows, o Comando-N en macOS.)

5. Creando la Instancia Retrofit

Para emitir peticiones de red a una API RESTFUL con Retrofit, necesitamos crear una instancia usando la clase Retrofit Builder y configurarla con una URL base.

Crea un nuevo sub-paquete dentro del paquete data y llámalo remote. Ahora, dentro de este paquete, crea una clase Java y llámala RetrofitClient. Esta clase creará un semifallo Retrofit en el método getClient(String baseUrl) y lo devolverá al llamador.

Como mencioné anteriormente, Retrofit necesita una URL base para construir su instancia, así que le pasaremos una URL cuando llamemos a RetrofitClient.getClient(String baseUrl). Esta URL será entonces usada para construir la instancia en la línea 13. También estamos especificando el convertidor JSON que necesitamos (Gson) en la línea 14.

6. Creando la Interfaz API

Dentro del paquete remoto, crea una interfaz y llámala APIService. Esta interfaz contiene métodos que vamos a usar para ejecutar peticiones HTTP tales como POST, PUT, y DELETE. Comencemos con la petición POST.

Viendo la clase APIService, tenemos un método savePost(). Encima del método está la anotación @POST, que indica que queremos ejecutar una petición POST cuando este método es llamado. El valor de argumento para la anotación @POST es el punto fina---que es /posts. Así que la URL completa sería http://jsonplaceholder.typicode.com/posts.

De acuerdo, ¿pero qué sobre el @FormUrlEncoded? Esto indicará que la petición tendrá su tipo MIME (un campo de encabezado que identifica el formato del cuerpo de una petición o respuesta HTTP) establecido a application/x-www-form-urlencoded y también que sus nombres de campo y valores serán codificados en UTF-8 antes de ser codificados en URI. La anotación @Field("key") con nombre de parámetro debería empatar el nombre que la API espera. Retrofit convierte implícitamente los valores a cadenas de texto usando String.valueOf(Object), y las cadenas son entonces codificadas en forma de URL. Los valores null son ignorados.

Por ejemplo, llamar a APIService.savePost("My Visit To Lagos", "I visited...", 2) produce un cuerpo de petición de title=My+Visit+To+Lagos&body=I+visited...&userId=2

Usando la Anotación @Body

También podemos usar la anotación @Body en un parámetro de método de servicio en lugar de especificar un cuerpo de petición estilo formulario con un número de campos individuales. El objeto será serializado usando la instancia Converter de Retrofit especificada durante la creación. Esto solo es usado cuando se realiza una operación POST o PUT.

7. Creando la Utilidades API

Vamos a crear una clase de utilidad. Así que crea una clase en data.remote y llámala ApiUtils. Esta clase tendrá la URL base como una variable estática y también proporcionará la interfaz APIService con un método estático getAPIService() al resto de nuestra aplicación.

Asegúrate de que terminas la URL base con una /.

8. Creando el Diseño

El archivo activity_main.xml es el diseño para nuestro MainActivity. Este diseño tendrá un campo text field para el título del post y otro para el cuerpo del post. También incluye un botón para enviar el post a la API.

9. Ejecutando la petición POST

En el método onCreate() en MainActivity, inicializamos una instancia de la interfaz APIService (línea 14). También inicializamos los campos EditText y un botón enviar que llamará al método sendPost() cuando se le de clic (línea 22).

En el método sendPost(String, String) en la clase MainActivity, pasamos el título y el cuerpo del post a este método. Lo que hará este método es llamar a nuestro método de interfaz de servicio API savePost(String, String) cuyo trabajo es ejecutar una petición POST enviando el título y el cuerpo a la API. El método showResponse(String response) mostrará la respuesta en la pantalla.

El método savePost(String, String) de la instancia mAPIService de nuestro APIService devolverá una instancia Call que tiene un método llamado enqueue(Callback callback).

Entendiendo enqueue()

enqueue() envía de manera asíncrona la petición y notifica a tu aplicación con un callback cuando una respuesta regresa. Ya que esta petición es asíncrona, Retrofit maneja la ejecución en el hilo de fondo para que el hilo de la UI principal no sea bloqueada o interfiera con esta.

Para usar el método enqueue(), tienes que implementar dos métodos callback: onResponse() y onFailure(). Solo uno de estos métodos será llamado en respuesta a una petición dada.

  • onResponse(): invocado para una respuesta HTTP recibida. Este método es llamado para una respuesta que puede ser correctamente manejada incluso si el servidor devuelve un mensaje de error. Así que si obtienes un código de estado 404 o 500, este método aún será llamado. Para obtener el código de estado para que puedas manejar situaciones basadas en estos, puedes usar el método response.code(). También puedes usar el método isSuccessful() para averiguar si el código de estado está en el rango 200-300, indicando éxito.
  • onFailure(): invocado cuando una excepción de red ocurre comunicando al servidor o cuando una excepción inesperada ocurrió manejando la petición o procesando la respuesta.

Peticiones Síncronas

Para realizar una petición síncrona, puedes usar el método execute() en una instancia Call. Pero ten en cuenta que los métodos síncronos en el hilo main/UI bloqueará cualquier acción del usuario. ¡Así que no ejecutes métodos síncronos en el hilo main/UI de Android! En su lugar ejecútalos en un hilo de segundo plano.

Usando RxJava

RxJava fue integrado en Retrofit 1 por defecto, pero en Retrofit 2 necesitas incluir algunas dependencias extra. Retrofit viene con un adaptador por defecto para ejecutar instancias Call. Así que puedes cambiar el mecanismo de ejecución de Retrofit para incluir RxJava incluyendo el CallAdapter de RxJava. Estos son los pasos:

Paso 1

Agrega las dependencias.

Paso 2

Agrega el nuevo CallAdapter RxJavaCallAdapterFactory.create() cuando construyas una instancia Retrofit (línea 5).

Paso 3

Actualiza el método APIService savePost(String title, String body, String userId) para que se vuelva un Observable.

Paso 4

Cuando hagas las peticiones, nuestro suscriptor anónimo responde al flujo del observable que emite eventos, en nuestro caso Post. El método onNext es entonces llamado cuando nuestro suscriptor recibe cualquier evento, que entonces es pasado a nuestro método showResponse(String response).

Revisa Comenzando Con ReactiveX en Android por Ashraff Hathibelagal para aprender más acerca de RxJava y RxAndroid.

10. Probando la Aplicación

En este punto, puedes ejecutar la aplicación y dar clic al botón enviar cuando hayas ingresado un título y cuerpo. La respuesta de la API se mostrará debajo del botón enviar.

final app screenshot

11. Ejecutando una petición PUT

Ahora que sabemos cómo ejecutar una petición POST, veamos cómo podemos ejecutar una petición PUT que actualice entidades. Agrega el siguiente método nuevo a la clase APIService.

Para actualizar un post desde la API, tenemos el punto final /posts/{id} con {id} siendo un contenedor para el id del post que queremos actualizar. La anotación @Path es el reemplazo nombrado en un segmento de ruta URL {id}. Ten en cuenta que los valores son convertidos a string usando String.valueOf(Object) y codificados en URL. Si el valor ya está codificado, puedes deshabilitar el codificado URL así: @Path(value="name", encoded=true).

12. Ejecutando una petición DELETE

También veamos cómo ejecutar una petición DELETE. Usando la API JSONPlaceholder, para borrar un recurso de post, el punto final requerido es /posts/{id} con el método HTTP DELETE. De vuelta a nuestra interfaz APIService, solo necesitamos incluir el método deletePost() que lo ejecutará. Pasamos el id del post al método, y es reemplazado en el segmento de ruta URL {id}.

13. Creando una Petición

Digamos que quieres darle a tus usuarios la habilidad de cancelar o abortar una petición. Esto es muy sencillo de hacer en Retrofit. La clase Retrofit Call tiene un método llamado cancel() que hará justo eso (línea 30 abajo). Este método disparará el método onFailure() en el callback.

Este método puede ser llamado, por ejemplo, si no hay conexión a internet o cuando una excepción inesperada ocurre creando la petición o manejando la respuesta. Así que para saber si la petición fue cancelada, usa el método isCanceled() en la clase Call (línea 18).

Conclusión

En este tutorial, aprendiste sobre Retrofit: por qué deberías usarlo y cómo integrarlo en tu proyecto para realizar peticiones POST, PUT, DELETE y cancel. También aprendiste cómo integrar RxJava con este. En mi siguiente artículo sobre usar Retrofit, te mostraré cómo subir archivos.

Para aprender más sobre Retrofit, refiérete a la documentación oficial. ¡Y revisa algunos de nuestros otros tutoriales y cursos sobre desarrollo Android aquí en Envato Tuts+!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.