viernes, 22 de febrero de 2013

Devolver xml, json o html con RESTEasy

RESTEasy
En esta serie de artículos sobre los servicios web REST hemos visto hasta el momento como hacer un programa sencillo Hola Mundo con RESTEasy y como crear un cliente Java y Javascript de ese servicio web para consumirlo desde javascript en una aplicación web y desde un programa java usando la librería RESTEasy. En un servicio web REST podemos devolver datos en varios formatos, ya sea texto plano, html, json o xml, en esta entrada veremos como devolver datos en los dos últimos y que anotaciones usar para que las cabeceras devueltas en la petición sean las correctas, que ventajas nos puede aporta y que problemas nos puede resolver.

Antes unos pequeños apuntes de porque nos puede interesar devolver json o xml. Unos de los motivos es que a medida que las aplicaciones web están ganando en complejidad estas están tendiendo a delegar en el cliente la parte de visualización en vez de ser el servidor el que devuelva html formateado directamente. Además de evitar cierta carga de proceso en el servidor y delegarla en los clientes ofreciendo una interfaz REST de la apliccación permitimos que terceros desarrollen sus propias aplicaciones y se integren consumiendo los servicios que ofrecemos.

Una vez explicadas algunas ventajas, veamos el ejemplo de como devolver json o xml en el servicio REST, en el siguiente código el servicio HelloWorldResource devolverá los datos de un objeto a través de los métodos getMensajeJSON y getMensajeXML. Los métodos del servicio puede anotarse con @Produces indicando el formato de los datos que se devuelve, en la clase MediaType hay constantes para muchos formatos. Si el formato en el que devolvemos los datos no está definido en la clase MediaType podemos definir uno específico con @Produces("text/html"):

La anotación @Produces es muy importante en el servicio REST ya que los métodos getMensajeJSON y getMensajeXML tienen especificada la misma ruta de petición en la etiqueta @Path, ¿como sabe entonces el servicio REST en que formato se han devolver los datos si la URL solicitada es la misma para ambos casos? La respuesta es empleando la información enviada en las cabeceras del protocolo http, más concretamente empleando la cabecera Accept que en este protocolo indica en que formato quiere el cliente los datos. En muchas aplicaciones es habitual encontrarse en que se realizan peticiones al servidor especificando como Accept text/html y resulta que el servidor devuelve los datos en formato json, xml u otro, la aplicación funcionará bien pero lo hace empleando el protocolo http de forma incorrecta, esto no ocurre con los servicios REST que en función de lo que se solicita en la petición así es el formato de los datos devueltos. En la siguiente imagen pude verse la cabecera Accept de la petición enviada por el cliente javascript.


En el ejemplo se devuelve una clase POJO con varios atributos que usa las anotaciones @XmlRootElement, @XmlElement, @XmlAttribute para indicar los datos y la forma de los datos a generar como resultado:

Para el cliente java desde el punto de vista del que lo usa la comunicación con el servidor y el formato en el que se transmiten los mensajes es transparente.


En el cliente javascript si usamos el formato json nos será más cómodo tratarlo en el navegador: En las siguientes imágenes las peticiones que se realizan desde el navegador con el cliente javascript, en la columna type se puede ver el tipo de datos devuelto en las peticiones:


Para que el ejemplo funcione deberemos incluir las dependencias org.jboss.resteasy:resteasy-jaxb-provider:2.3.5.Final y org.jboss.resteasy:resteasy-jettison-provider:2.3.5.Final.

Para finalizar, comentar que la combinación de ofrecer en la aplicación una API REST junto con librerías como Backbone.js que proporcionan un Modelo-Vista-Controlador (MVC) en el navegador accediendo al servidor para consumir el servicio puede dar lugar a aplicaciones más flexibles y fáciles de desarrollar entre otras cosas. Y esa es la tendencia hacia la que están evolucionado las aplicaciones web a medida que el propio lenguaje javascript y los navegadores aumentan sus capacidades.

En el siguiente enlace puedes encontrar el código fuente completo de este ejemplo y probarlo tu mismo en un servidor de aplicaciones como Tomcat. La siguiente entrada será como integrar RESTEasy con un framework de desarrollo web como Apache Tapestry.

Referencia:
http://www.jboss.org/resteasy
http://backbonejs.org
Código fuente completo del ejemplo Hola Mundo con RESTEasy