REST

Proyecto en Eclipse con Jersey(JAX-RS 2.0)+Tomcat+JSON

En los últimos años se pretende llevar más allá la separación entre datos y representación: se está pasando de un modelo en el que la separación se hace en el servidor (con desarrollos MVC) a transferir la responsabilidad de la vista al cliente, con las nuevas “single-page web application” basadas en HTML5.

De este modo se pretende que la comunicación que se lleva a cabo entre el cliente y el servidor sea la mínima posible, siendo datos la información que se transfiere. Los más usados últimamente son los datos en formato JSON, que se adaptan perfectamente a los clientes hechos en JavaScript. Un paradigma de comunicación puede ser por lo tanto un servidor RESTful, tal y como vimos en el ejemplo de AngularJS y CouchDB (que implementa de forma nativa un servidor Web con comunicación RESTful para dar acceso a los datos).

Hay en el mercado diferentes opciones para crear un servidor RESTful con diferentes tecnologías. Al fin y al cabo se trata de implementar un servidor en el puerto 80 (normalmente) que responde al protocolo HTTP y a sus diferentes comandos (GET, POST, HEAD…). Podríamos implementar nosotros mismos uno cualquiera en cualquier lenguaje. La comunicación se realiza a través de diferentes protcolos, como XML, JSON, Texto plano… No pienses que RESTful se emplea para desarrollar aplicaciones Web: también es un buen método para desarrollar la interoperabilidad entre diferentes sistemas.

Dentro de la oferta de Java, existen diferentes opciones, como por ejemplo usar un MVC como Struts2 y añadirle un plug-in para RESTful. Este plugin se encargará de traducir las peticiones HTTP y sus cabeceras a las diferentes acciones que hayamos desarrollado. También existe la opción de usar JAX-RS, que desde Java6 forma parte del estándar J2EE.

JAX-RS es un framework que nos permite desarrollar de una manera sencilla y fiable servicios web de tipo RESTful. Su implementación de referencia es el framework Jersey. Así pues, en este artículo vamos a ver cómo podemos montar en Eclipse un proyecto de base que funcione sobre Tomcat y además la comunicación se lleve a cabo a través de objetos JSON.

Antes de comenzar, hay que destacar que podemos apoyarnos en Maven para todo el proceso. Recomiendo el uso del plugin m2e que ya tratamos en otro artículo del blog (https://mysticalpotato.wordpress.com/2014/01/21/maven-en-eclipse-m2e/).

1. Crear Proyecto Web dinámico con Eclipse y Tomcat 7

Esto no debería ser problema. Como siempre, ir a File->New->Dynamic Web Project

newDynamicProject

Si además en el último paso indicamos que queremos crear el fichero web.xml mucho mejor (aunque posteriormente vamos a sobreescribirlo).

2. Incluir las bibliotecas de Jersey y Jackson

Ahora dos alternativas, dependiendo de si usamos o no Maven:

Si NO usamos Maven

a. Ir a https://jersey.java.net/download.html y descargar el fichero “Jersey JAX-RS 2.0 RI bundle” y descomprimirlo en nuestro disco duro.
b. Copiar las bibliotecas de los tres directorios a WEB-INF/lib (o incluirlas en el proyecto, si es así, tener en cuenta que hay que añadirlas en el deploy).

También debemos instalar Jackson, que es el parser para transformar a JSON las comunicaciones del servidor RESTFUL:

a. Ir a http://wiki.fasterxml.com/JacksonDownload y descargar la última versión
b. Copiar las bibliotecas a WEB-INF/lib (o incluirlas en el proyecto, si es así, tener en cuenta que hay que añadirlas en el deploy).

En el caso de que estemos usando Maven

En primer lugar podemos convertir un proyecto que no tengan Maven en uno que sí lo tenga. En Eclipse con m2e es muy sencillo: pulsamos con el botón auxiliar del ratón en el proyecto, luego en Configure->Convert to Maven Projects

jax1

Una vez tenemos el proyecto convertido a Maven podemos incluir las dependencias en el fichero pom.xml; se puede hacer tanto con la interfaz gráfica de Eclipse como editando el código. Habría que incluir las siguientes:


<dependencies>
 <dependency>
 <groupId>org.glassfish.jersey.containers</groupId>
 <artifactId>jersey-container-servlet</artifactId>
 <version>2.5.1</version>
 </dependency>
 <dependency>
 <groupId>org.glassfish.jersey.core</groupId>
 <artifactId>jersey-client</artifactId>
 <version>2.5.1</version>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.jaxrs</groupId>
 <artifactId>jackson-jaxrs-json-provider</artifactId>
 <version>2.2.3</version>
 </dependency>
 </dependencies>
 

Las dos primeras dependencias indican que se va a emplearn Jersey versión 2.5.1 (la última cuando se creó este post). El siguiente, com.fasterxml.jackson.jaxrs, es provider de JSON para poder transformar la comunicación RESTful a este protocolo.

3. Crear el web.xml para que la aplicación funcione correctamente en nuestro contenedor de servlets (Tomcat 7 en nuestro caso)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 <display-name>js6</display-name>

<servlet>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
 <init-param>
 <param-name>jersey.config.server.provider.packages</param-name>
 <param-value>com.mysticalpotato.JAX</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>

<welcome-file-list>
 <welcome-file>index.html</welcome-file>
 <welcome-file>index.htm</welcome-file>
 <welcome-file>index.jsp</welcome-file>
 <welcome-file>default.html</welcome-file>
 <welcome-file>default.htm</welcome-file>
 <welcome-file>default.jsp</welcome-file>
 </welcome-file-list>
</web-app>

¿Qué es importante en este web.xml?

Principalmente que existe un servlet (org.glassfish.jersey.servlet.ServletContainer, solo en el caso de JAX-RS 2) que se encarga de capturar todas las peticiones que le lleguen al subdirectorio “rest” del servidor y que las procesará como RESTful: tendrá en cuenta la URL y las operaciones de la cabecera y las asignará a determinadas clases. El directorio “rest” puede ser cambiado por el que nosotros indiquemos.

Además hay otro parámetro muy interesante, jersey.config.server.provider.packages, que indica en qué paquete están las clases a las que se tiene que mapear las peticiones RESTful. No existe un fichero de asignación como tal, sino que, a través de anotaciones, en cada clase se indica la URL a la que responde cada una, y dentro de ella, qué métodos responden a cada tipo de operaciones y qué resultado o entrada procesan. En el caso del ejemplo está asignado a “com.mysticalpotato.JAX” pero puedes cambiarlo por lo que creas conveniente.

4. Crear una aplicación básica

Una vez tenemos configuradas las bibliotecas y el contenedor de servlets, podemos comenzar a desarrollar nuestro primer servicio:

En primer lugar vamos a crear una sencilla clase de datos, un POJO que contiene tres características de un coche. Lo albergamos en el paquete com.mysticalpotato.data:

package com.mysticalpotato.data;

public class Coche {

 String marca;
 String modelo;
 long potencia;
 public String getMarca() {
 return marca;
 }
 public void setMarca(String marca) {
 this.marca = marca;
 }
 public String getModelo() {
 return modelo;
 }
 public void setModelo(String modelo) {
 this.modelo = modelo;
 }
 public long getPotencia() {
 return potencia;
 }
 public void setPotencia(long potencia) {
 this.potencia = potencia;
 }
}

De este clase implementaremos un objeto que será el que se transforme de modo automático a formato JSON cuando se publique el punto de acceso RESTful;

Creamos un paquete para albergar los servicios RESTful, que coincida con lo indicado en el fichero web.xml como parámetro del servlet RESTful. En el caso de este ejemplo tenemos com.mysticalpotato.JAX.

Dentro vamos a crear la clase “Coches” con el siguiente código:

package com.mysticalpotato.JAX;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.mysticalpotato.data.Coche;

@Path("coches")
public class Coches {

@GET
 @Produces(MediaType.APPLICATION_JSON)
 public Coche getIt() {
 Coche c = new Coche();
 c.setMarca("Ferrari");
 c.setModelo("F45");
 c.setPotencia(430);
 return c;
 }
}

Cosas importantes:

  • Se ha declarado “coches” como la URL de acceso a este punto RESTful. Entonces la URL será del tipo http://servidor.com/rest/coches. El “directorio” rest viene de la confijguración del servlet en el web.xml.
  • Cuando se haga una petición de tipo GET (la que se hace cuando se pide una página en un navegador), se accederá al método getIt(). La razón es que hemos indicado esto con la anotación @GET.
  • El tipo de datos de salida será de tipo JSON, y funcionará además porque hemos usado el proveedor Jackson, que se encargará de hacerlo funcionar.

La salida será:

{"marca":"Ferrari","modelo":"F45","potencia":430}

Un aspecto importante: será necesario indica que cuando el proyecto se despliegue en el servidor, también lo hagan las librerías de Maven que se han indicado. Para ello ir a propiedades del proyecto->Deployment Assembly y añadir las dependencias de Maven o de los ficheros si se ha hecho en manual.

Anuncios