icono_twiter icono LinkedIn
Alvaro Cuesta Viñolo

Consultor tecnológico de desarrollo de proyectos informáticos.

Puedes encontrarme en Autentia: Ofrecemos servicios de soporte a desarrollo, factoría y formación

Somos expertos en Java/JEE

Ver todos los tutoriales del autor

Fecha de publicación del tutorial: 2012-02-21

Tutorial visitado 5.412 veces Descargar en PDF
Servicios REST con Jersey

Servicios REST con Jersey.


0. Índice de contenidos.

1. Introducción.

En este tutorial vamos a explorar las posibilidades que nos ofrece Jersey para validar los mensajes XML entrantes contra el esquema que tengamos definido.
También trataremos la gestión de excepciones que nos ofrece desacopladas de los servicios.

Aquí está la guía de usuario de la versión 1.11.

Para iniciaros con Jersey y sus anotaciones teneis un tutorial muy bueno de Germán.
Jersey: la implemetación de RESTFull de Sun

2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 15' (2.8 GHz Intel Core 2 Duo, 4GB DDR3 SDRAM).

  • Sistema Operativo: Mac OS X Snow Leopard 10.6.3.

  • NVIDIA GeForce 9600M GT 512Mb.

  • Toshiba 500 Gb. 5400r.p.m.

3. Implementación del servicio.

Para este tutorial vamos a utilizar la versión 1.11 de Jersey.
Comenzamos añadiendo la dependencia en el pom.xml

	
		com.sun.jersey
		jersey-server
		1.11
	

No vamos a centrarnos en la propia funcionalidad a implementar en el servicio, sino simplemente en su diseño. En la clase RestService definimos el servicio REST que queremos publicar.


package com.adictosaltrabajo.rest;

...

@Path("/rest/track/")
public class RestService {
    
    @POST
    @Path("/add")
    @Consumes(MediaType.APPLICATION_XML)
    @Produces(MediaType.TEXT_PLAIN)
    public String postTrack(Track track,
            @Context ServletContext servletContext) {
        
        // ...
        
        return "200";
    }
        
}

4. Configuración.

En el server.xml tenemos que añadir la configuración del servlet de Jersey.
También se configura el paquete donde se encuentran las clases anotadas.

	Track Example
	          
	    
	        JerseyTest
	        com.sun.jersey.spi.container.servlet.ServletContainer
	           
	            com.sun.jersey.config.property.resourceConfigClass
	            com.sun.jersey.api.core.PackagesResourceConfig
	        
	        
	            com.sun.jersey.config.property.packages
	            com.adictosaltrabajo.rest                        
	                
	        1
	    
	    
	        JerseyTest
	        /*
	    

5. Validación del cuerpo del mensaje

Creamos la clase TrackBodyReader que es la encargada de contruir el objeto de la petición, esto lo hace Jersey por si mismo pero implementando esta interfaz asumimos el control de la construcción del objeto, permitiéndonos validar contra el esquema el mensaje de la petición. De esta manera desacoplamos la validación de los mensajes de la propia lógica del servicio.
Podríamos realizar cualquier tipo de validación, en este caso simplemente comprobamos que el XML este bien formado y cumpla el esquema.

package com.adictosaltrabajo.rest;

...
  
@Provider
@Consumes("application/xml")
public class TrackBodyReader implements MessageBodyReader<Track> {

    private JAXBTrackBuilder builder = new JAXBTrackBuilder();

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations,
            MediaType mediaType) {

        return type.isAssignableFrom(Track.class);
    }

    @Override
    public Track readFrom(Class<Track> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
            InputStream entityStream) throws IOException, WebApplicationException {
        
        try {
            return builder.unmarshal(entityStream);

        } catch (Exception ex) {
            throw new WebApplicationException(ex);
        }
    }
}

6. Gestión de excepciones

Jersey nos proporciona una interfaz muy sencilla que nos permite capturar las excepciones que le definamos y devolver un mensaje encapsulándolas de forma que podamos construir una respuesta con la propia traza o lo que creamos oportuno.
En este ejemplo se devuelven en texto plano, pero sería fáctible incluirlas en una respuesta XML ó JSON.
En este caso capturamos únicamente las excepciones de tipo "WebApplicationException" manteniendo aislado el propio servicio de la gestión de las mismas.

package com.adictosaltrabajo.rest;

...

@Provider
public class JAXBExceptionMapper implements ExceptionMapper<WebApplicationException> {
   
    @Override
    public Response toResponse(WebApplicationException exception) {
        return Response.status(Status.BAD_REQUEST).
            entity(exception.getMessage()).
            type(MediaType.TEXT_PLAIN).
            build();
    }
}

7. Conclusión.

Como hemos visto, la propia implementación del servicio está desacoplada de la validación de los mensajes entrantes y de la gestión de excepciones, esto nos permite tener clases con muy pocas líneas de código con una funcionalidad muy concreta y acotada.

Espero que os haya sido de utilidad.
Cualquier aclaración, duda o sugerencia podéis incluirla en la zona de comentarios.

Un saludo.
Alvaro Cuesta.

A continuación puedes evaluarlo:

Regístrate para evaluarlo

Por favor, vota +1 o compártelo si te pareció interesante

Share |
Anímate y coméntanos lo que pienses sobre este TUTORIAL: