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)
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
Publicar un comentario