Tutorial - REST con java (JAX-RS 2.0)

27
Tutorial - REST con Java (JAX-RS) usando Jersey www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López REST con Java usando Jersey Presenta Ing. Abimael Desales López https://www.facebook.com/JavaDevelopersMexico JavaDevelopersMexico en Google + El conocimiento es libre y está en búsqueda de que lo hagas tuyo, sólo necesitas práctica y paciencia

Transcript of Tutorial - REST con java (JAX-RS 2.0)

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

REST con Java usando Jersey

Presenta

Ing. Abimael Desales López

https://www.facebook.com/JavaDevelopersMexico

JavaDevelopersMexico en Google +

“El conocimiento es libre y está en búsqueda de que lo hagas tuyo, sólo necesitas práctica y paciencia”

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Tutorial - REST con Java (JAX-RS) usando Jersey

Copyright © 2015 JavaDevelopersMexico 10/08/2015

Web services RESTful con Java (Jersey / JAX-RS)

Este tutorial explica cómo desarrollar web services RESTful en Java con Jersey la implementación de referencia de JAX-RS.

En este tutorial usamos los siguientes artefactos de software

Eclipse 4.4 (Luna)

Java 1.8.0_45, Tomcat 7.0 JAX-RS 2.0 (con Jersey 2.19).

Tabla de Contenido

Audiencia

1. REST - Representational State Transfer

1.1. ¿Qué es REST?

1.2. Métodos HTTP

1.3. Web Services RESTFul

2. JAX-RS con Jersey

2.1. JAX-RS

2.2. Jersey

2.3. Anotaciones JAX-RS

3. Instalación de Jersey

4. Contenedor Web

5. Prerrequisitos

6. Crea tu primer Webservice RESTful

6.1. Crea un nuevo proyecto web

6.2. Agrega los JARs de Jersey

6.3. Clase Java

6.4. Define el Servlet dispatcher de Jersey

6.5. Corre tu servicio rest

7. Crea un cliente

8. Web services RESTful y JAXB

8.1. Crea un proyecto

8.2. Crea un cliente

9. Webservice RESTful CRUD

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

9.1. Proyecto

9.2. Crea un formulario HTML simple

9.3. Servicio Rest

9.4. Corre

9.5. Crea un cliente

9.6. Usando el servicio REST vía una página HTML

Bibliografía y Webgrafía

Audiencia

Este tutorial está diseñado para profesionales de software quienes quieren aprender sobre

servicios web RESTful en pasos simples y fáciles. Este tutorial te proporcionará

conocimientos sobre los conceptos de servicios web RESTful, y después de completar este

tutorial estarás en un nivel intermedio de expertise desde donde puedes subir por ti mismo a

un nivel de expertise más alto a través de la práctica.

1. REST - Representational State Transfer

1.1. ¿Qué es REST?

REST es un estilo arquitectural que está basado en estándares web y el protocolo HTTP.

REST fue descrito por primera vez por Roy Fielding en el 2000.

En una arquitectura REST todo es un recurso. Un recurso es accesado vía una interfaz

común basada en los métodos HTTP estándar.

En una arquitectura basada en REST generalmente tienes un servidor REST que

proporciona acceso a los recursos y un cliente REST que accesa y modifica los recursos

REST.

Cada recurso debe soportar las operaciones HTTP comunes. Los recursos son identificados

por IDs globales (las cuales típicamente son URIs).

REST permite que los recursos tengan diferentes representaciones, p.e., texto, XML, JSON,

etc. El cliente REST puede preguntar por una representación específica vía el protocolo

HTTP (negociación de contenido).

1.2. Métodos HTTP

Los métodos PUT, GET, POST DELETE, y OPTIONS generalmente son usados en

arquitecturas basadas en REST.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

La siguiente tabla proporciona una explicación de estas operaciones.

GET Define un acceso de lectura del recurso sin efectos colaterales . El recurso nunca es

cambiado vía una request GET, p.e., la request no tiene efectos colaterales

(idempotente).

PUT Crea un nuevo recurso. También de debe ser idempotente

DELETE Usado para remover un recurso. Las operaciones son idempotentes. Pueden ser

repetidas sin llevar a diferentes resultados.

POST Usado para actualizar un recurso existente o crear un nuevo recurso

OPTIONS Usado para obtener las operaciones soportadas por un recurso

1.3. Web services RESTFul

Los web services RESTFul están basados en métodos HTTP y el concepto de REST. Un

web service RESTFul típicamente define la URI base URI para los servicios, los tipos MIME

soportados (XML, text, JSON, definido por el usuario,...) y el conjunto de operaciones (POST,

GET, PUT, DELETE) que son soportadas.

2. JAX-RS con Jersey

2.1. JAX-RS

Java define el soporte de REST vía la Java Specification Request (JSR) 311. Esta

especificación es llamada JAX-RS (la Java API for RESTful Web Services). JAX-RS usa

anotaciones para definir la relevancia de REST en las clases Java.

2.2. Jersey

Jersey es implementación de referencia para la especificación JSR 311.

La implementación Jersey provee una librería para implementar webservices Restful en un

contenedor de servlets Java.

En el lado del servidor Jersey provee una implementación de servlet que escanea las clases

predefinidas para identificar los recursos RESTful. En tu archivo de configuración web.xml

debes registrar este servlet para tu aplicación web.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

La implementación Jersey también proporciona una librería cliente para comunciarse con un

webservice RESTful.

La URL base de este servlet es:

http://tu_dominio:puerto/nombre-despliegue/url-pattern/path_de_clases_rest

Este servlet analiza la request HTTP entrante y selecciona la clase correcta y método para

responder a esta request. Esta selección está basada en anotaciones en la clase y métodos.

Una aplicación web REST consiste, por lo tanto, de clases (recursos) y servicios. Estos dos

tipos típicamente son mantenidos en diferentes packages ya que el servlet Jersey será

instruido vía el web.xml para que escanee ciertos packages para las clases de datos.

JAX-RS soporta la creación de XML y JSON vía la Java Architecture for XML Binding (JAXB).

2.3. Anotaciones JAX-RS

Las anotaciones más importantes en JAX-RS son listados en la siguiente tabla.

Tabla 1. Anotaciones JAX-RS

Anotación Descripción

@PATH(tu_path) Asigna el path a la URL base + /tu_path. La URL base está basada

en el nombre de tu aplicación, el servlet y la URL pattern del archivo

de configuración web.xml.

@POST Indica que el método siguiente responderá a una request POST

HTTP.

@GET Indica que el método siguiente responderá a una request GET

HTTP.

@PUT Indica que el siguiente método responderá a una request PUT

HTTP.

@DELETE Indica que el siguiente método responderá a una request DELETE

HTTP.

@Produces(MediaType.TEXT_PLAIN[,

more-types])

@Produces define qué tipo MIME es entregado por un método

anotado con @GET. En el ejemplo se produce texto ("text/plain").

Otros ejemplos serían "application/xml" o "application/json".

@Consumes(type[, mas-tipos]) @Consumes define qué tipo MIME es consumido por este método.

@PathParam

Usado para inyectar valores de la URL en un parámetro del método.

De esta forma inyectas, por ejemplo, el ID de un recurso en el

método para obtener el objeto correcto.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

El path completo a un recurso está basado en la URL base y la anotación @PATh en tu

clase.

http://tu_dominio:puerto/nombre-despliegue/url-pattern/path_de_clases_rest

3. Instalación de Jersey

Descarga la distribución Jersey como archivo zip desde el sitio de descarga de Jersey.

El zip contiene el JAR de la implementación Jersey y sus dependencias core. No proporciona

dependencias para JArs de tecerceros más allá de aquellos para el soporte de JSON y

JavaDoc.

4. Contenedor Web

Para este tutorial puedes usar cualquier contenedor web, por ejemplo Tomcat o la Google

App Engine.

Si quieres usar Tomcat como contenedor de servlet por favor mira Eclipse WTP y Apache

Tomcat para las instrucciones sobre cómo instalar y usar Eclipse WTP y Apache Tomcat.

Alternativamente también podrías usar la Google App Engine para correr la parte del servidor de los siguientes ejemplos de REST. Si usas la Google App Engine, no tienes que instalar y configure Tomcat.

Tip

Si estás usando GAE/J, tienes que crear proyectos de App Engine en vez de Dynamic Web Project. La siguiente descripción está basada en Apache Tomcat.

5. Prerrequisitos

Antes de proceder con este tutorial debes tener una comprensión básica del lenguaje Java, editores de texto, IDEs, servidores web, etc. Debido a que vamos a desarrollar aplicaciones de web services usando RESTful, será bueno que tengas conocimientos sobre otras tecnologías web como HTML, CSS, AJAX etc.

6. Crea tu primer Webservice RESTful

6.1. Crea un nuevo proyecto web

Crea un nuevo Dynamic Web Project llamado it.adesales.primer.rest.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Haz click en Next

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Asegúrate de crear el descriptor de deployment web.xml.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Seleccionando la casilla Generate web.xml deployment descriptor y además cambia el nombre

de content directory por Web en vez de WebContent para estandarizar la aplicación.

6.2. Agrega los JARs de Jersey

Copia todos los JARs de tu descarga de Jersey (los que hay dentro de las tres carpetas de

librerías, api, ext y lib) en la carpeta WEB-INF/lib.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

6.3. Clase Java

Crea la siguiente clase Java en el package it.adesales.primer.rest.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

package it.adesales.primer.rest;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

// Plain old Java Object no extienden de clases o implementan una interface

// La clase registra sus métodos para la request GET HTTP usando la anotación @GET.

// Usando la anotación @Produces, define que puede entregar varios tipos MIME, texto

// XML y HTML.

// Por defaul, el navegador solicita el tipo MIME HTML.

//Asigna el path a la URL base + /hola

@Path("/hola")

public class Hola {

// Este método es llamado si se solicita TEXT_PLAIN

@GET

@Produces(MediaType.TEXT_PLAIN)

public String sayPlainTextHola() {

return "Hola Jersey";

}

// Este método es llamado si se solicita XML

@GET

@Produces(MediaType.TEXT_XML)

public String sayXMLHola() {

return "<?xml version=\"1.0\"?>" + "<hello> Hola Jersey" + "</hello>";

}

// Este método es llamado si se solicita HTML

@GET

@Produces(MediaType.TEXT_HTML)

public String sayHtmlHola() {

return "<html> " + "<title>" + "Hola Jersey" + "</title>"

+ "<body><h1>" + "Hola Jersey" + "</body></h1>" + "</html> ";

}

}

Esta clase se registra a sí misma como un recurso get vía la anotación @GET. Vía la anotación

@Produces define que entrega el texto y los tipos MIME HTML. Además define vía la anotación @Path que sus servicios están disponibles bajo la URL hola.

El navegador siempre solicitará el tipo MIME HTML. Para ver la versión texto, puedes usar

alguna herramienta como curl.

6.4. Define el despachador de Servlet de Jersey

Necesitas registrar Jersey como el despachador de servlet para solicitudes REST. Abre el archivo web.xml y modifícalo a lo siguiente.

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

<display-name>it.adesales.primer.rest</display-name>

<servlet>

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

<servlet-name>Jersey REST Service</servlet-name>

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

<!-- Registra recursos y proveedores bajo package com.vogella.jersey.first.-->

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>it.adesales.primer.rest</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>

</web-app>

El parámetro jersey.config.server.provider.packages define en qué package buscará

Jersey clases de web service. Esta propiedad debe apuntar a tus clases de recursos. El URL pattern define la parte de la URL base donde tu aplicación será colocada.

6.5. Corre tu servicio rest

Corre tu aplicación web en Eclipse.

Debes ser capaz de accesar tus recursos bajo la siguiente URL en el navegador: http://localhost:8080/it.adesales.primer.rest/rest/hola

En mi caso también pruebo con una herramienta de nombre Postman, disponible para

Chrome, recomiendo que la utilicen y jueguen con ella para que se familiaricen :

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Este nombre es derivado del "display-name" definido en el archivo web.xml, aumentado con

el URL-pattern del servlet-mapping y la anotación @Path hola de tu archivo de clase. Debes obtener el mensaje "Hola Jersey".

El navegador solicita la representación HTML de tu recurso. En el siguiente capítulo vamos a escribir un cliente que leerá la representación XML.

7. Crea un cliente

Jersey contiene una librería cliente REST que se puede usar para probar o construir un cliente real en Java. El uso de esta librería es demostrado en el siguiente ejercicio.

Crea un nuevo proyecto Java y agrega el package it.adesales.primer.rest.cliente y agrega los JARs de Jersey al proyecto y al build path del proyecto. Crea la siguiente clase de test.

package it.adesales.primer.rest.cliente;

import java.net.URI;

import javax.ws.rs.client.Client;

import javax.ws.rs.client.ClientBuilder;

import javax.ws.rs.client.WebTarget;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

import javax.ws.rs.core.UriBuilder;

import org.glassfish.jersey.client.ClientConfig;

public class Test {

public static void main(String[] args) {

ClientConfig config = new ClientConfig();

Client client = ClientBuilder.newClient(config);

WebTarget target = client.target(getBaseURI());

String response = target.path("rest").

path("hola").

request().

accept(MediaType.TEXT_PLAIN).

get(Response.class)

.toString();

String plainAnswer =

target.path("rest").path("hola").request().accept(MediaType.TEXT_PLAIN).get(String.class);

String xmlAnswer = target.path("rest").path("hola").request().accept(MediaType.TEXT_XML).get(String.class);

String htmlAnswer=

target.path("rest").path("hola").request().accept(MediaType.TEXT_HTML).get(String.class);

System.out.println(response);

System.out.println(plainAnswer);

System.out.println(xmlAnswer);

System.out.println(htmlAnswer);

}

private static URI getBaseURI() {

return UriBuilder.fromUri("http://localhost:8080/it.adesales.primer.rest").build();

}

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

}

8. Web services RESTful y JAXB

JAX-RS soporta la creación automática de XML y JSON vía JAXB. Si deseas una introducción

en XML por favor revisa el Tutorial Java y XML. Si deseas una introducción en JAXB por favor

revisa JAXB. Puedes continuar este tutorial sin leer estos tutoriales, pero ellos contienen más

información de fondo si quieres conocer mas sobre dichos temas.

8.1. Crea el proyecto

Crea un nuevo Dynamic Web Project llamado it.adesales.rest.jaxb. Asegúrate de seleccionar

el check para generar el descritor de deployment web.xml y renombrar la carpeta

WebContent a Web, como en el ejemplo anterior .

Copia todos los JARs de Jersey JARs a la carpeta WEB-INF/lib.

Crea tu clase de dominio Todo bajo el package it.adesales.rest.jaxb.model.

package it.adesales.rest.jaxb.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

// JAX-RS soporta un mapeo automático de clases JAXB anotadas a XML y JSON

// ¿No es esto cool?

public class Todo {

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

private String resumen;

private String descripcion;

public String getResumen() {

return resumen;

}

public void setResumen(String resumen) {

this.resumen = resumen;

}

public String getDescripcion() {

return descripcion;

}

public void setDescripcion(String descripcion) {

this.descripcion = descripcion;

}

}

Crea la siguiente clase de recurso. Esta clase simplemente retorna una instancia de la clase

Todo.

package it.adesales.rest.jaxb.service;

import it.adesales.rest.jaxb.model.Todo;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

@Path("/todo")

public class TodoRecurso {

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

// Este método es llamado si la request es XML

@GET

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public Todo getXML() {

Todo todo = new Todo();

todo.setResumen("Este es mi primer todo XML");

todo.setDescripcion("Este es mi primer todo XML");

return todo;

}

// Esto puede ser usado para probar la integración con el navegador

@GET

@Produces({ MediaType.TEXT_XML })

public Todo getHTML() {

Todo todo = new Todo();

todo.setResumen("Este es mi primer todo HTML");

todo.setDescripcion("Este es mi primer todo HTML");

return todo;

}

}

Cambia tu web.xml a lo siguiente.

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

<display-name>it.adesales.rest.jaxb</display-name>

<servlet>

<servlet-name>Jersey REST Service</servlet-name>

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

<!-- Register resources and providers under com.vogella.jersey.first

package. -->

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>it.adesales.rest.jaxb.service</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>

</web-app>

Corre tu aplicación web en Eclipse y valida que puedes accesar tu servicio. Tu aplicación debe estar disponible bajo la siguiente URL.

http://localhost:8080/com.vogella.jersey.jaxb/rest/todo

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

8.2. Crea un cliente

Crea un nuevo proyecto Java it.adesales.rest.jaxb.client y agrega los JARs de Jersey al proyecto y al build path del proyecto. Crea la siguiente clase de test.

package it.adesales.rest.jaxb.client;

import java.net.URI;

import javax.ws.rs.client.Client;

import javax.ws.rs.client.ClientBuilder;

import javax.ws.rs.client.WebTarget;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.UriBuilder;

import org.glassfish.jersey.client.ClientConfig;

public class TodoTest {

public static void main(String[] args) {

ClientConfig config = new ClientConfig();

Client client = ClientBuilder.newClient(config);

WebTarget target = client.target(getBaseURI());

// Obtiene el XML

String htmlResponse = target.path("rest").path("todo").request()

.accept(MediaType.TEXT_XML).get(String.class);

// Obtiene el XML para la aplicación

String xmlResponse = target.path("rest").path("todo").request()

.accept(MediaType.APPLICATION_XML).get(String.class);

// Para una response JSON también agrega las librerías de Jackson a tu

//aplicación web. En este caso también cambiarías el registro del cliente a

// ClientConfig config = new ClientConfig().register(JacksonFeature.class);

// Get JSON for application

// System.out.println(target.path("rest").path("todo").request()

// .accept(MediaType.APPLICATION_JSON).get(String.class));

System.out.println(htmlResponse);

System.out.println(xmlResponse);

}

private static URI getBaseURI() {

return

UriBuilder.fromUri(“http://localhost:8080/it.adesales.rest.jaxb“).build(); }

}

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

9. Webservice RESTful CRUD

En esta sección vamos a crear un web service RESTful CRUD (Create, Read, Update, Delete). Permitirá mantener una lista de TODOs en tu aplicación web vía llamadas HTTP.

9.1. Proyecto

Crea un nuevo dynamic web project llamado it.adesales.rest.jaxb.crud y agrega las librerías de Jersey. Cambia el archivo web.xml al siguiente.

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

<display-name>it.adesales.rest.crud</display-name>

<servlet>

<servlet-name>Jersey REST Service</servlet-name>

<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

<!-- Registar recursos y proveedores bajo com.vogella.jersey.first -->

<init-param>

<param-name>jersey.config.server.provider.packages</param-name>

<param-value>it.adesales.rest.crud.recursos</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>

</web-app>

Crea el siguiente modelo de datos y un Singleton que sirve como el proveedor de datos para el

modelo. Nosotros usamos la implementación basada en una enumeración, puedes probar con otras opciones como usar objetos Mocks. Por favor revisa los links para más detalles. La clase Todo está anotada con una anotación JAXB. Véase Java y XML para aprender sobre JAXB.

package it.adesales.rest.crud.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

public class Todo {

private String id;

private String resumen;

private String descripcion;

public Todo(){}

public Todo (String id, String resumen){

this.id = id;

this.resumen = resumen;

}

public String getId() {

return id;

}

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

public void setId(String id) {

this.id = id;

}

public String getResumen() {

return resumen;

}

public void setResumen(String resumen) {

this.resumen = resumen;

}

public String getDescripcion() {

return descripcion;

}

public void setDescripcion(String descripcion) {

this.descripcion = descripcion;

}

}

package it.adesales.rest.crud.dao;

import java.util.HashMap;

import java.util.Map;

import it.adesales.rest.crud.model.Todo;

public enum TodoDao {

instance;

private Map<String, Todo> contentProvider = new HashMap<>();

private TodoDao() {

Todo todo = new Todo("1", "Aprende REST");

todo.setDescripcion("Lee mi artículo completo");

contentProvider.put("1", todo);

todo = new Todo("2", "Haz algo");

todo.setDescripcion("Visita mis sitios de Java Developers México");

contentProvider.put("2", todo);

}

public Map<String, Todo> getModel(){

return contentProvider;

}

}

9.2. Crea un formulario HTML simple

El servicio REST puede usarse vía formularios HTML. El siguiente formulario HTML permitirá

postear nuevos datos al servicio. Crea una carpeta de nombre pages dentro de la carpeta Web y dentro de esta crea la siguiente página llamada crea_todo.html.

<!DOCTYPE html>

<html>

<head>

<title>Formulario para crear un nuevo recurso</title>

</head>

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

<body>

<form action="../it.adesales.rest.crud/rest/todos" method="POST">

<label for="id">ID</label>

<input name="id" />

<br/>

<label for="resumen">Resumen</label>

<input name="resumen" />

<br/>

Descripción:

<TEXTAREA NAME="descripcion" COLS=40 ROWS=6></TEXTAREA>

<br/>

<input type="submit" value="Submit" />

</form>

</body>

</html>

9.3. Servicio Rest

Crea las siguientes clases que se usarán como recursos REST.

package it.adesales.rest.crud.recursos;

import javax.ws.rs.Consumes;

import javax.ws.rs.DELETE;

import javax.ws.rs.GET;

import javax.ws.rs.PUT;

import javax.ws.rs.Produces;

import javax.ws.rs.core.Context;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Request;

import javax.ws.rs.core.Response;

import javax.ws.rs.core.UriInfo;

import javax.xml.bind.JAXBElement;

import it.adesales.rest.crud.dao.TodoDao;

import it.adesales.rest.crud.model.Todo;

public class TodoRecurso { @Context

UriInfo uriInfo;

@Context

Request request;

String id;

public TodoRecurso(UriInfo uriInfo, Request request, String id) {

this.uriInfo = uriInfo;

this.request = request;

this.id = id;

}

//Integración de la Aplicación

@GET

@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})

public Todo getTodo() {

Todo todo = TodoDao.instance.getModel().get(id);

if(todo==null)

throw new RuntimeException("Get: Todo con " + id + " no encontrado");

return todo;

}

// para el navegador

@GET

@Produces(MediaType.TEXT_XML)

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

public Todo getTodoHTML() {

Todo todo = TodoDao.instance.getModel().get(id);

if(todo==null)

throw new RuntimeException("Get: Todo con " + id + " no encontrado ");

return todo;

}

@PUT

@Consumes(MediaType.APPLICATION_XML)

public Response putTodo(JAXBElement<Todo> todo) {

Todo c = todo.getValue();

return putAndGetResponse(c);

}

@DELETE

public void deleteTodo() {

Todo c = TodoDao.instance.getModel().remove(id);

if(c==null)

throw new RuntimeException("Delete: Todo con " + id + " no encontrado");

}

private Response putAndGetResponse(Todo todo) {

Response res;

if(TodoDao.instance.getModel().containsKey(todo.getId())) {

res = Response.noContent().build();

} else {

res = Response.created(uriInfo.getAbsolutePath()).build();

}

TodoDao.instance.getModel().put(todo.getId(), todo);

return res;

}

}

package it.adesales.rest.crud.recursos;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import javax.ws.rs.Consumes;

import javax.ws.rs.FormParam;

import javax.ws.rs.GET;

import javax.ws.rs.POST;

import javax.ws.rs.Path;

import javax.ws.rs.PathParam;

import javax.ws.rs.Produces;

import javax.ws.rs.core.Context;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Request;

import javax.ws.rs.core.UriInfo;

import com.vogella.jersey.todo.dao.TodoDao;

import com.vogella.jersey.todo.model.Todo;

// Mapeará el recurso a la URL todos

@Path("/todos")

public class TodosRecurso {

// Permite insertar objetos contextuales en la clase,

// p.e. ServletContext, Request, Response, UriInfo

@Context

UriInfo uriInfo;

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

@Context

Request request;

// Retorna la lista de todos al usuario en el browser

@GET

@Produces(MediaType.TEXT_XML)

public List<Todo> getTodosBrowser() {

List<Todo> todos = new ArrayList<Todo>();

todos.addAll(TodoDao.instance.getModel().values());

return todos;

}

// Retorna la lista de todos para las aplicaciones

@GET

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public List<Todo> getTodos() {

List<Todo> todos = new ArrayList<Todo>();

todos.addAll(TodoDao.instance.getModel().values());

return todos;

}

// retorna el número de todos

// Usa http://localhost:8080/it.adesales.rest.crud/rest/todos/conteo

// para obtener el número total de registros

@GET

@Path("conteo")

@Produces(MediaType.TEXT_PLAIN)

public String getCount() {

int count = TodoDao.instance.getModel().size();

return String.valueOf(count);

}

@POST

@Produces(MediaType.TEXT_HTML)

@Consumes(MediaType.APPLICATION_FORM_URLENCODED)

public void newTodo(@FormParam("id") String id,

@FormParam("resumen") String resumen,

@FormParam("descripcion") String descripcion,

@Context HttpServletResponse servletResponse) throws IOException {

Todo todo = new Todo(id, resumen);

if (descripcion != null) {

todo.setDescripcion(descripcion);

}

TodoDao.instance.getModel().put(id, todo);

servletResponse.sendRedirect("../crea_todo.html");

}

// Define que el siguiente parámetro path después de todos es tratado

// como un parámetro y pasado al TodoResources

// Permite al type http://localhost:8080/it.adesales.rest.crud/rest/todos/1

// 1 será tratado como parámetro todo y pasado a TodoResource

@Path("{todo}")

public TodoRecurso getTodo(@PathParam("todo") String id) {

return new TodoRecurso(uriInfo, request, id);

}

}

Este TodosRecurso usa la anotación @PathParam para definir que el id es insertado como

parámetro.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

9.4. Corre

Corre tu aplicación web en Eclipse y prueba la disponibilidad de tu servicio REST bajo: http://localhost:8080/it.adesales.rest.crud/rest/todos . Debes ver la representación XML de tus elementos TODO.

Para ver el conteo de los elementos de TODO usa la dirección http://localhost:8080/it.adesales.rest.crud/rest/todos/conteo

para ver un TODO existente usa "http://localhost:8080/it.adesales.rest.crud/rest/todos/{id}", p.e., http://localhost:8080/it.adesales.rest.crud/rest/todos/1 para ver el TODO con ID 1. Actualmente tenemos sólo TODOs con los ids 1 y 2, todas las otras requests darán como resultado un código de error HTTP.

En la siguiente pantalla se muestra la versión solicitada en XML del todo con id=1.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

En la siguiente pantalla se muestra el todo con id=2 desde la herramienta de chrome Postman.

La siguiente pantalla es de una request POST, ingresando los parámetros y el Content-Type por la herramienta Postman.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Si consultamos los recursos disponibles después de haber emitido la request POST a través de la herramienta Postman, podremos ver lo siguiente desde el navegador o la misma tool:

Por favor, nota que con el navegador sólo puedes emitir solicitudes GET HTTP. En el siguiente capítulo usaremos las librerías cliente de Jersey para emitir get, post y delete.

Sólo quisiera hacer una aclaración, debido a que otra aplicación ocupa el puerto 8080 de mi equipo, he tenido que cofigurar Tomcat para que ocupe el puerto 80 en vez del 8080 que trae por default, por ello en mis requests después de localhost omito el puerto ya que es el default 80 donde un equipo escucha requests HTTP.

Puedes omitir el siguiente punto si utilizas la herramienta Postman ya que es el cliente.

9.5. Crea un cliente

Para probar tu servicio puedes crear una nueva clase en el proyecto servidor. Este proyecto

ya tiene todas las librerías requeridas en el classpath, de forma que este es más rápido que crear un nuevo proyecto.

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Crea la siguiente clase.

package com.vogella.jersey.todo.client;

import java.net.URI;

import javax.ws.rs.client.Client;

import javax.ws.rs.client.ClientBuilder;

import javax.ws.rs.client.Entity;

import javax.ws.rs.client.WebTarget;

import javax.ws.rs.core.Form;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

import javax.ws.rs.core.UriBuilder;

import org.glassfish.jersey.client.ClientConfig;

import it.adesales.rest.crud.model.Todo;

public class Tester {

public static void main(String[] args) {

ClientConfig config = new ClientConfig();

Client client = ClientBuilder.newClient(config);

WebTarget service = client.target(getBaseURI());

// crea un todo

Todo todo = new Todo("3", "Blabla");

Response response =

service.path("rest").path("todos").path(todo.getId()).request(MediaType.APPLICATI

ON_XML).put(Entity.entity(todo,MediaType.APPLICATION_XML),Response.class);

// El código de retorno debe ser 201 == recurso creado

System.out.println(response.getStatus());

// Obtén los Todos

System.out.println(service.path("rest").path("todos").request().accept(MediaType.

TEXT_XML).get(String.class));

// // Obtén JSON para la aplicación

//

System.out.println(service.path("rest").path("todos").request().accept(MediaType.

APPLICATION_JSON).get(String.class));

// Obtiene el XML para la aplicación

System.out.println(service.path("rest").path("todos").request().accept(MediaType.

APPLICATION_XML).get(String.class));

//Obtiene Todo con id 1

Response checkDelete =

service.path("rest").path("todos/1").request().accept(MediaType.APPLICATION_XML).

get();

//Elimina Todo con id 1

service.path("rest").path("todos/1").request().delete();

//Obtiene todos los Todos con id 1 quedeben ser eliminados

System.out.println(service.path("rest").path("todos").request().accept(MediaType.

APPLICATION_XML).get(String.class));

//Crea un Todo

Tutorial - REST con Java (JAX-RS) usando Jersey

www.facebook.com/JavaDevelopersMexico Ing. Abimael Desales López

Form form =new Form();

form.param("id", "4");

form.param("resumen","Demostración de la librería cliente para formularios");

response =

service.path("rest").path("todos").request().post(Entity.entity(form,MediaType.AP

PLICATION_FORM_URLENCODED),Response.class);

System.out.println("Response del formulario" + response.getStatus());

//Obtiene todos los todos, id 4 deben haber sido creados

System.out.println(service.path("rest").path("todos").request().accept(MediaType.

APPLICATION_XML).get(String.class));

}

private static URI getBaseURI() {

return

UriBuilder.fromUri("http://localhost:8080/it.adesales.rest.crud").build();

}

}

9.6. Usando el servicio REST vía página HTML

El ejemplo anterior contiene un formulario que llama a un método post de tu servicio rest.

Bibliografía y Webgrafía

El presente artículo ha sido conformado por ejemplos de libros y de artículos de la web, de los cuales se pretende ofrecer lo mejor de cada uno, una mención especial a la página de Lars Vogel y a tutorialespoint.com, gracias por sus buenos artículos, ha sido el comienzo y aquí hemos buscado mejorarlos, estos se mencionan a continuación:

1.- http://www.vogella.com/

2.- http://www.tutorialspoint.com/

3.- https://es.wikipedia.org/wiki/Representational_State_Transfer

4.- Kalali Masoud y Bhakti Mehta, Developing RESTful Services with JAXRS 2.0, WebSockets and

JSON, PACKT Publishing, UK, 2013, 128 p.

5.- Burke, Bill. RESTful Java with JAXRS 2.0. O’ Really Editorial, Second Edition, USA, 2014, 392 p.

Siéntete libre de escribirme y hacerme llegar tus opiniones.