Jersey la implementacion de Sun para JAX-RS

    Jersey es la implementacion de Sun para JAX-RS.
    Jax-RS es un api para servicios Web basado en REST .
     REST es la "filosofia-reglas" en las que se basó el estandar HTTP cuando se creo. Especifica el como deben ser las comunicaciones a traves de protocolo HTTP.
   
    Rest define varios principios para el protocolo http: (por ejemplo)
    1.Cada recurso en la web se corresponde con una unica url
        Asi, un registro libro en una aplicacion, se corresponde por ejemplo con su url:
       
        http://www.servilibros.com/libros/1
       
        Cuando se pregunte o visite esta url se accede al recurso del libro.
   
    2.Sobre un recurso existen varios metodos con los que interactuar con él.
   
Asi el protocolo HTTP definió (entre otros) estos metodos principales:
        GET : devuelve info del recursore
        POST: da de alta un nuevo recuros
                Para usarlo podriamos hacer una peticion HTTP con el method = POST
                sobre el recurso http://www.servilibros.com/libros/
        PUT: modifica la informacion de un registro
        DELETE: borra un recurso.
   
   
        De esta forma se definio http, como una "comunidad" de recursos y una forma de interactuar con ellos.
       
   
    Esta filosofia no se "respeto" a lo largo de los tiempos para dar paso a frameworks y aplicaciones, que sobre un    recursos http hacian lo que hubiera que hacer sin respetar la arquitectura de la red que estaban utilizando.
   
    Por el  contrario, los WebServices y otras interacciones de tipo machine-to-machine si que lo respetan y se basan en ella.
   
    JERSEY,
   
    Pues eso, Jersey es una implementacion de Sun sobre el estandar Jax-rs basado en rest, que nos va a servir  para hacer servicios web y que respondan al protocolo HTTP.
   
    En resumen y asi mal dicho, Jersey en nuestra aplicacion funciona como un servlet que se define
    que acepte todas las peticiones (en el web.xml) .
    Tiene configuración para decirle que clases van a actuar como “servicios”(servlets) y algo mas.
   
    Para usarlo necesitamos:
    0.Crear proyecto web con maven
       (mira este post si tienes dudas creando proyectos con maven
       http://danipenaperez.blogspot.com/2011/12/modulos-dependientes-en-maven.html)
      
    1.Importar las dependencias de del api Jax-RS y su implementacion Jersey:
   
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>1.8</version>
    </dependency>
   <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.8</version>
    </dependency>
   
    2.Ahora que tenemos las librerias de Jersey, vamos a meter el servlet que se encargara de escuchar
    las peticiones y redirigir a nuestros servicios. En el web.xml metemos la siguiente definicion de servlet:
   
    <!--SErvlet de JAx RS jersey-->
    <servlet> <!-- aqui hay documentacion http://www.vogella.de/articles/REST/article.html -->
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <!--esta propiedad le dice donde estan los servlets que debe buscar anotaciones-->
        <init-param>
          <param-name>com.sun.jersey.config.property.packages</param-name>
          <param-value>org.dppware.facade.rest</param-value> <!--El package que decidas-->
        </init-param>
        <!-- Le dice cual es el directorio raiz de las jsp, por si se devuleve por viewable-->
        <init-param>
            <param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
            <param-value>/WEB-INF/jsp</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>Jersey REST Service</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
   
   
    Meditante el "property.packages" le definimos que paquetes de nuestro proyecto pueden contener
    servicios Rest. Y le estamos diciendo que todas la peticiones sobre "/rest/", las resuelva Jersey.
   
    3. Definir un servicio Rest.
    Creamos una clase dentro del paquete que especificamos (org.dppware.facade.rest) y especificamos
    las propiedades de nuestro servicio. (bajo que url respondera y que cabeceras HTTP admitira).EJ:
   
    @Path("/libros")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_JSON})
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_JSON})
    public class LibroFacade {
   
       
    }
   
   
    Vemos, que respondera a las peticiones sobre  : http://localhost/applicationName/rest/libros.
   
    Expone que acepta XML , JSON y devuelve XML y JSON tambien. Podriamos, decirle que no admita JSON  o que las peticiones por JSON deben ir por otro servicio, asi que podriamos crear otro o lo que
    se nos ocurra como configuracion, vamos lo que sea...
   
   
    4.Implementamos los metodos sobre los Method HTTP (GET, POST,PUT,DELETE):
   
    @Path("/libros")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public class LibroFacade {
   
        @GET
        @Path("{resourceId: \\d+}")
        public Response getResourceBasic(@PathParam("resourceId") int id) ;

        @POST
        public Response create(Libro obj) ;

        @PUT
        @Path("{resourceId: \\d+}")
        public Response update(@PathParam("resourceId") int id, Libro obj) ;

        @DELETE
        @Path("{resourceId: \\d+}")
        public Response delete(@PathParam("resourceId") int id) ;
   
   
       
    }
   
    Con esta configuracion, cuando se hagan peticion sobre /libros , Jersey redigira a esta clase
    y segun el method de la cabecera, redigira a un metodo o a otro
    (Segun como especifiquemos el @Path  en cada metodo:
    @GET, @POST, @PUT, @DELETE .
    (Para el uso de anotaciones es necesario JDK 1.5 o superior, recuerdalo)
   
    Tambien podemos especificar el path sobre "/libros/(lo que pongamos en @path a nivel de metodo)"
    Asi , mediante una exp regular , le estamos diciendo que solo acepte digitos con esto "\\d+".
    En este caso 1, 2, 3 etc.....   libros/1,  libros/2 vamos libros/idRecurso.
   
    Ademas, este parametro estara disponible en nuestro metodo bajo la variable "id" (integer).
   
   
    5.Implementar algun metodo y su respuesta. Las respuestas son tambien bajo protocolo http, asi que    Jersey, ofrece unas respuestas en su libreria que se corresponde con las respuestas mas comunes para http.

    Pej:
HTTP 200 --OK , HTTP 201 --Created(sera la respuesta para un post), HTTP 500 --error servidor,
HTTP 403 Forbidden--Prohibido, etc...
(mira http://en.wikipedia.orgwiki/List_of_HTTP_status_codes )
   
    Vamos a meter algo de codigo:
   
        @GET
        @Path("{resourceId: \\d+}")
        public Response getResourceBasic(@PathParam("resourceId") int id) {
            System.out.println("LibroFacade -->get/encontrar con id "+ id);
            Libro res = bbdd.findLibro(id); //por ejemplo
            if(res == null){
                return Response.status(Status.NOT_FOUND).build(); //devuelve HTTP code 404
            }
            return Response.ok(res).build(); //devuelve 200 y el contenido de la respuesta es el objeto res
        }
   
   
    Vemos, que Jersey se encarga de devolver y generar toda la info de protocolo HTTP para la respuesta    en el primer caso devuelve un 404 y en el segundo devuelve un 200 (si encuentra el libro) y aparte mete la informacion del libro.
   
    La informacion del libro la puede devolver en XML o JSON, segun especificara el cliente en su cabecera   http al llamar al metodo.
   
    JAx-rs para convertir la clase Libro en formato XML o JSON utiliza la libreria JAXB. (aunque puede integrar  con otras librerias de parseo). Asi que si nuestra clase libro esta mapeada con anotaciones JAXB, Jersey la transformara de forma "transparente" para nosotros y lo devolvera en la respuesta.
   
    Un ejemplo muy sencillo de mapeo para el recurso libro con Jaxb podria ser:
   
    @XmlRootElement(name="libro")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Libro {
   
        @XmlAttribute //como es atributo, lo mete en la etiqueta del padre <libro id="1" name="blabla">
        private Integer id;
        @XmlAttribute        //<libro id="1" name="blabla">
        private String name;
       
        public Libro(){
        }
       
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
   
    }
   
   
    Para poder mapear con JSON , es necesario especificar esta propiedad en el servlet de jersey:
        <!-- que use json-->
        <init-param>
             <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
           <param-value>true</param-value>
        </init-param>
     (Fijate, que para que resuelva Jsonn, fue necesario meter la dependencia jersey-json arriba)
   
   
   

Comentarios

Entradas populares de este blog

Reiniciar usuario de SVN Subversion

Subir campos Blob a BBDD (Oracle) con Java

Reproducir mp3 con Java