[JEE] Servicios REST - primer contacto

Iniciado por Gus Garsaky, Abril 25, 2015, 11:20:18 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Un servicio web nos provee mucha utilidad y flexibilidad. Al estar basado en la arquitectura Cliente Servidor, nos permite mucha escalabilidad horizontal. Para empezar, crearemos una POJO:

Código: java

public class Song implements Serializable {
private Integer id;
private String name;
private Long duration;

public Song() {

}
public Song(Integer id, String name, Long duration) {
this.id = id;
this.name = name;
this.duration = duration;
}
// getters y setters
}


Ésta clase es un Java Bean, no un POJO. Un POJO debe cumplir los siguientes requisitos:

  • Variables privadas
  • Un constructor vacío
  • Getters y setters
  • No implementar nada del exterior

    Un POJO no debe implementar ni heredar nada. Por otro lado, un JavaBean, tiene como requisito implementar la interface Serializable. La interface Serializable hace que el objeto sea descompuesto/recompuesto en una secuencia de Bytes, permitiendo así que éste objeto pueda ser transportado en diferentes ámbitos como pueden ser: ficheros, sockets, peticiones HTTP, etc.

    Un JavaBean debe de implementar Serializable porque éste va a ser transportado o persistido, por lo que, si no implementara la interface Serializable, no podría ser posible su transporte.

    Ahora, hagamos una clase que sirva como servicio o comúnmente llamado DAO:

    Código: java

    public class SongService {
    private static final Map<Integer, Song> songs;
    static {
    songs = new HashMap<>();
    songs.put(1, new Song(1, "Enter Sandman", 3500L));
    songs.put(2, new Song(2, "The day that never comes", 5000L));
    songs.put(3, new Song(3, "Whiskey in the jar", 4000L));
    }
    public static Song find(Integer id) {
    return songs.get(id);
    }
    // otros metodos que simulan el crud (create, findAll, update, remove)
    }


    Ésta clase simula un servicio o DAO. Dispone de un método find, que recibe un entero que representa a un ID. Éste ID es buscado es el Map y es retornado hacia el contexto en que se llamó.

    Ahora, resta crear nuestro REST:

    Código: java

    @Path("/music")
    @Stateless
    public class MusicServiceREST {
    @Path("/find/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Song findMetallica(@PathParam("id") Integer id) {
    return SongService.find(id);
    }
    // otros servicios (findAll, update, remove, etc)
    }


    Aquí es necesario explicar algunas cosillas:


    • @Path indica una ruta y ésta ruta será mapeada; es decir, todas las peticiones que se hagan a dicha ruta las interceptará el REST.

    • @Stateless indica que dicha clase es un EJB (Enterprise Java Bean). Un Enterprise Java Bean es una especificación de Java EE, el cual trae una serie de novedades como: JMS, control de concurrencia, transacciones (flujos), servicios de nombre y directorios. Éste concepto lo dejaremos para después. Al estar la clase anotada con @Stateless estamos diciendo que esa clase es un EJB y que soporta las características antes mencionadas. Por ejemplo, al soportar transacciones, aquí se puede inyectar un EntityManager y que el EJB sea el encargado de manejar las transacciones (cuando se abren y cierran). En éste caso, al no haber entidades no es necesario.

    • @Produces indica qué MIME retornará la petición a dicha ruta (@Path). Aquí podemos especificar que se devolverá el MIME que se crea necesario: text/plain, text/html, application/json, application/xml, etc. En nuestro caso hemos dicho que se devolverá un objeto JSON, que es la representación de nuestro objeto Song.

    • @PathParam indica el parámetro que se va a formatear en el tipo de dato deseado. En nuestro caso, el parámetro enviado lo especificamos entre llaves, y se llamará id ({id}), así que, formateamos éste parámetro a entero para poder buscar al objeto Song con dicho ID.

    Es necesario registrar nuestro REST. Para ello, solo basta hacer:

    Código: java

    @ApplicationPath("api")
    public class RestApplication extends Application {
        @Override
        public Set<Class<?>> getClasses() {
        Set<Class<?>> rests = new HashSet<>();
        rests.add(MusicServiceREST.class);
        return rests;
        }
    }


    Solo debemos de agregar el class de los REST que tengamos creados para registrarlos. Una vez hecho lo anterior, ya tenemos todo hecho. Ahora, para probarlo, solo tipea la url:

    Código: html5
    http://localhost:8080/tu_proyecto/api/music/find/3


    La URL anterior, buscará la canción con el ID 3 y lo retornará como JSON:

    Código: javascript
    {
        "id": 3,
        "name": "Whiskey in the jar",
        "duration": 4000L
    }


    En caso se quiera consumir algo, por ejemplo, un XML, debemos de utilizar la anotación @Consumes:

    Código: java
    @Path("/upload")
    @Consumes(MediaType.APPLICATION_XML)
    @Produces(MediaType.TEXT_HTML)
    public String upload(final InputStream IS) {
        /* proceso */
    }


    El caso anterior es sin utilizar JAXB. Si utilizáramos JAXB no necesitaríamos el InputStream. Como la petición puede venir desde todo tipo de clientes, es necesario capturarla con un InputStream para poder procesarla.

    Ésta es la forma básica en que se crea un servicio REST en Java. Generalmente, se usa un REST como capa intermedia entre el acceso a datos y el cliente.



    Librerías necesarias:

  • jersey-server
  • jersey-json