Ejemplo básico Jersey 1.18 (JAX-RS 1.1) + Tomcat 7.0.55 (con envío/recepción de XML/JSON)

Jersey 1.18 es una implementación de la API JAX-RS 1.1, la cual permite la creación de servicios tipo REST en Java de una manera "estándar". El ejemplo requiere las siguientes librerías:

  • jackson-core-asl-1.9.13.jar
  • jersey-bundle-1.18.1.jar

No se requiere el archivo web.xml.

Estructura

El proyecto tiene la siguiente estructura (siguiendo la estructura de un proyecto típico de eclipse):

C:.
|
|
+---src
|   +---domain
|   |       Message.java
|   |
|   \---rest
|           Hello.java
|           MyApplication.java
|           Pojo.java
|
\---WebContent
    \---WEB-INF
        \---lib
                jackson-core-asl-1.9.13.jar
                jersey-bundle-1.18.1.jar

MyApplication.java

Utilizando la anotación @ApplicationPath, se define en esta clase la URI base (rest) para todos los recursos (clases con anotación @Path) de esta aplicación. En otras palabras, todas las peticiones que encajen con el patrón /rest/* pasarán por el servlet (configurado tras bambalinas) de Jersey.

package rest;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest")
public class MyApplication extends Application {

}


Hello.java

Se define un recurso "simple" con dos "subrecursos".

package rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

@Path("hello")
public class Hello {

    @GET
    public String sayHello() {
        return "Hello!";
    }

    @GET
    @Path("{name}")
    public Response sayHello(@PathParam("name") String name) {
        return Response.status(200)
                       .entity("Hello " + name + "!")
                       .type("text/plain; charset=utf-8")
                       .build();
    }

}

El segundo subrecurso tiene una ruta especial con un nombre entre llaves ({,}). Significa que esa parte de la URI se utilizará como parámetro del método (con la ayuda de la anotación @PathParam).


Message.java

La siguiente clase es la versión en Java de un objeto JSON o XML que se envía o recibe en una petición:

package domain;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Message {

    private String sender;
    private String content;
   
    public Message() {
    }

    public Message(String sender, String content) {
        this.sender = sender;
        this.content = content;
    }

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

NOTA: La anotación @XmlRootElement es una anotación de JAX-B. Le indicará a Jackson cómo debe realizar la conversión de objeto a XML o viceversa. Jackson es una librería que permite convertir de objeto a JSON y viceversa. Algunas otras librerías (por ejemplo, MOXy, JSON-P, Jettison) requieren otras anotaciones o no las requieren.


Pojo.java

Se definen dos "subrecursos" un poco más "complejos". Uno de ellos obtiene datos del Query String y otro del Payload (o cuerpo del mensaje).

package rest;

import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import domain.Message;

@Path("pojo")
public class Pojo {

    @Context
    private ServletContext ctx;

    @GET
    @Produces(MediaType.APPLICATION_XML)
    public Message sendMsg(@QueryParam("sender") String sender,
            @QueryParam("content") String content) {
        return new Message(sender, content);
    }

    @POST
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Message sendMsg(Message msg) {
        System.out.printf("Sender: %s, Content: %s%n", msg.getSender(), msg.getContent());
        return new Message("server", "OK");
    }

}

El segundo subrecurso puede recibir un XML o un JSON en el payload. También devuelve XML o JSON. Jersey utiliza los encabezados HTTP para saber el tipo de dato recibido (Content-Type) y el tipo de dato a devolver (Accept).


Probando con cURL

cURL es una utilería que se ejecuta desde una Terminal o desde el Símbolo de Sistema.

Si ejecutamos los siguiente comandos:

curl http://localhost:8080/webapp/rest/hello
curl http://localhost:8080/webapp/rest/hello/Java%20Mexico
curl http://localhost:8080/webapp/rest/hello/Pedro

Obtendremos:

~~~

Enviando datos en el query string:

curl "http://localhost:8080/webapp/rest/pojo?sender=Paul&content=%C2%A1Saludos!"

NOTA: En este comando se envían caracteres no ASCII, pero debido a las diferencias de codificación y decodificación (el Símbolo de Sistema utiliza IBM850 y el servidor UTF-8), no se reciben o muestran correctamente.

~~~

Enviando JSON, y recibiendo XML o JSON:

curl -H "Content-Type: application/json" -H "Accept: application/json" -d {"""sender""":"""Paul""","""content""":"""¡Hola!"""} http://localhost:8080/webapp/rest/pojo
curl -H "Content-Type: application/json" -H "Accept: application/xml" -d {"""sender""":"""Paul""","""content""":"""¡Hola!"""} http://localhost:8080/webapp/rest/pojo

NOTA: En el Símbolo del Sistema de Windows, una comilla doble intermedia se escapa tripicándola:

" -> """

~~~

Enviando XML, y recibiendo XML o JSON:

curl -H "Content-Type: application/xml" -H "Accept: application/xml" -d "<?xml version="""1.0""" encoding="""UTF-8""" standalone="""yes"""?><message><sender>Me</sender><content>Hello!</content></message>"  http://localhost:8080/webapp/rest/pojo
curl -H "Content-Type: application/xml" -H "Accept: application/json" -d "<?xml version="""1.0""" encoding="""UTF-8""" standalone="""yes"""?><message><sender>Me</sender><content>Hello!</content></message>"  http://localhost:8080/webapp/rest/pojo

En este caso, se puede decir que este recurso tiene dos representaciones: XML y JSON.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de paranoid_android

Muy Bueno

Muy Bueno