Mostrando entradas con la etiqueta rest. Mostrar todas las entradas
Mostrando entradas con la etiqueta rest. Mostrar todas las entradas

martes, 24 de marzo de 2009

REST Web Services con Jersey (III)

Los métodos de un recurso, pueden representar un sub-recurso si también se anotan con @Path

La URI especificada, es relativa a la ruta del recurso (especificada en la clase). Por ejemplo, la URI http://example.com/cantantes/ retornaría la lista de cantantes y la URI http://example.com/cantantes/13 retornaría la información relativa al cantante 13.

Se puede recuperar la información introducida con la anotación @PathParam

@Path("/holaMundo")
public class HolaMundo {
@GET
@Path("{id}")
@Produces("application/xml")
public String sayHolaXml(@PathParam("id") int id) {
return ""+id+"";
}
}

Al especificar que el tipo es int, si la URI fuera /holaMundo/ABC, automáticamente se retornaria un HTTP 404.
La ruta especificada en @Path puede incluir expresiones para controlar los valores admitidos. En el siguiente ejemplo, únicamente se admiten números hasta 3 dígitos:

@Path("{id: [0-9]{1,3}}")


La anotación @QueryParam permite inyectar un parámetro de query String. Por defecto, los recursos se instancian para cada petición para evitar problemas de concurrencia y se pueden anotar argumentos de un método y variables de clase u objeto.

La anotación @DefaultValue asigna un valor por defecto a variables inyectadas con @PathParam o @QueryParam entre otras (@MatrixParam, @CookieParam, @FormParam, @HeaderParam)


@Path("/holaMundo")
public class HolaMundo {
@GET
public String sayHola(@QueryParam("p") @DefaultValue("sin valor") String p) {
return p;
}
}


Si ejecutamos el siguiente cliente:

Client client = Client.create();
WebResource holaResource = client.resource("http://localhost:8080/RestTest/resources/holaMundo/");

out.println(holaResource.get(String.class));
out.println(holaResource.queryParam("p", "Hola :)").get(String.class));


Nos dará como salida:
sin valor
Hola :)

Los parámetros POST se pueden inyectar con @FormParam

@Path("/holaMundoPost")
public class HolaMundoPost {
@POST
@Consumes("application/x-www-form-urlencoded")
public String sayHola(@FormParam("p") @DefaultValue("sin valor") String p) {
return p;
}
}


La anotación @Consumes permite especificar el tipo MIME que acepta el método. Si no se especifica se acepta cualquiera.

El cliente quedaría de la siguiente forma:

Client client = Client.create();
WebResource postResource = client.resource(
"http://localhost:8080/RestTest/resources/holaMundoPost/");
out.println(postResource.post(String.class));
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("p", "Hola Post:)");
out.println(postResource
.type("application/x-www-form-urlencoded")
.post(String.class, formData));

lunes, 16 de marzo de 2009

REST Web Services con Jersey (II)

Seguimos donde los dejamos :-) En JAX-RS, podemos obtener distintas representaciones para la misma información, lo que se llama "content-negotiation". En las cabeceras de la petición mandada por el cliente, se incluye la cabecera "Accept" que indica los tipos MIME soportados/preferidos por el cliente y, en base a eso, generar una respuesta adecuada e indicándola en la cabecera "Content-Type".

La anotación @Produces permite especificar el tipo MIME que es capaz de generar un método.

package com.domborjo.rest;

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

@Path("/holaMundo")
public class HolaMundo {

@GET
@Produces("text/plain")
public String sayHola() {
return "Hola Mundo!";
}

@GET
@Produces("application/xml")
public String sayHolaXml() {
return "Hola Mundo!";
}
}

Para comprobar que funciona correctamente, Jersey proporciona una API para desarrollar clientes

package com.domborjo.client;

import static java.lang.System.out;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
public class JerseyClient {
public static void main(String[] args) {
Client client = Client.create();
WebResource holaResource = client.resource(
"http://localhost:8080/RestTest/resources/holaMundo");

out.println(holaResource.accept("text/plain").get(String.class));
out.println(holaResource.accept("application/xml").get(String.class));
out.println(holaResource.accept("text/plain",
"application/xml").get(String.class));
}
}

El código es bastante simple. El método accept() permite especificar los tipos MIME aceptados por el cliente (admite varios tipos ya que el parámetro es un vararg. Por defecto "text/plain"). El método get()
invoca la llamada GET y el parámetro es el tipo de la respuesta.

El resultado obtenido es:

Hola Mundo!
<datos>Hola Mundo!</datos>
Hola Mundo!

Nos vemos en el siguiente post!

viernes, 13 de marzo de 2009

REST Web Services con Jersey (I)

Representational State Transfer (REST) es un estilo de arquitectura, originalmente descrito por Roy Fielding en su disertación en 2000, para aplicaciones que especifica un conjunto de restricciones:

  • Protocolo cliente/servidor sin estado
  • Operaciones simples y claras: GET, POST, PUT y DELETE
  • Las funcionalidades y los datos son recursos, identificados y accedidos por una URI
  • Intercambio de información con interfaces y protocolos estándar
  • Uso de hypermedia para enlazar contenidos

Todo esto permite crear aplicaciones simples, facilmente escalables y cacheables, con buen rendimiento. Desde el punto de vista del cliente, puede obtener la información deseada con múltiples representaciones (texto, HTML, XML, JSON, JSONP, etc..) y puede guardar las páginas en favoritos.

JAX-RS es la API para desarrollar servicios web RESTful con Java y formará parte de Java EE 6. Por otro lado, Jersey, es la implementación de referencia de JAX-RS (existen otras implementaciones: Jboss RESTEasy, Restlet y Apache CXF)

Básicamente, REST propone utilizar la web correctamente, simplificando el desarrollo de Web Services.

Para empezar a desarrollar servicios web con Jersey, las librerías necesarias son en Java SE 6:

Se puede obtener información completa en
https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/jersey/dependencies.html

Las librerías deben situarse en el directorio lib de Tomcat.

Para desarrollar nuestra primera aplicación, debemos añadir el siguiente código en el web.xml, de forma que Jersey procese las peticiones dirigidas a nuestros servicios:

<servlet>
<servlet-name>JerseyServlet</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JerseyServlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>

Los recursos son POJO's anotados con @Path, que publica el recurso en esa URI. Las URI's, son relativas.
Los métodos públicos de un recurso permiten atender las peticiones de los clientes. Mediante anotaciones se indican los métodos HTTP soportados:

Así, nuestro primer ejemplo quedaría:


package com.domborjo.rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/holaMundo")
public class HolaMundo {
@GET
public String sayHola() {
return "Hola Mundo!";
}
}

Jersey escaneará las clases de nuestra aplicación y detectará automáticamente los recursos. Para comprobar que funciona correctamente basta con acceder a http://localhost[:PUERTO]/[CONTEXTO_APP]/resources/holaMundo

Espero que os haya gustado, queda mucho más por ver!