33
Integracion de EJB3 y JSF Integración de EJB3 y JSF Hace escaso tiempo que salió la versión final de JEE 5, versión que ha traido grandes cambios a la plataforma Java con respecto a la versión anterior. Se ha intentado hacer la plataforma más accesible a los programadores facilitando el desarrollo de las aplicaciones empresariales Java, y tomando como base la configuración por defecto, que tan buenos resultados parece haber generado a la plataforma Ruby on Rails. A pesar del esfuerzo realizado por el grupo de expertos encargado de definir las especificaciones que forman parte de JEE por simplificar el desarrollo de aplicaciones JEE, hay que tener en cuenta que JEE se trata de una plataforma compleja, alrededor de la cual se concentran usa serie de APIs y de conceptos, y que sin un conocimiento medio de éstos será difícil sacar el máximo partido a JEE, por lo que aunque a primera vista parezca sencillo el desarrollo de aplicaciones tendremos que intentar conocer al máximo todo aquello que se mueve a su alrededor si queremos sacar rendimiento a JEE. En este artículo/tutorial voy a intentar mostrar cómo desarrollar un prototipo de aplicación en la que integramos dos tecnologías que forman parte de esta renovada plataforma, EJB3 y Java Server Faces. Para ello voy a utilizar NetBeans 5.5, cuyo equipo también ha realizado grandes esfuerzos por simplificar al máximo el desarrollo de aplicaciones JEE con este IDE. La aplicación (si es que la podemos llamar así ) que vamos a desarrollar no podría ser más trivial, y simplemente se encarga de mostrar un listado de los clientes dados de alta en una base de datos, y da la opción de creación de nuevo clientes. Persistencia En NetBeans 5.5 tenemos integrado el servidor de aplicaciones open source Glassfish, y éste, a su vez, integra el motor de base de datos open source Derby. Glasshfish tiene configurado vía JNDI un acceso a esta base de datos con el nombre jdbc/__default, que es el que vamos a utilizar para desarrollar este proyecto. JPA es el nuevo framework de persistencia de Java, y se basa en gran medida en la solución open source más popular de persistencia que hasta ahora hemos tenido, Hibernate. JPA podemos utilizarlo tanto desarrollando con JEE como con JSE, lo cual supone un gran avance con respecto a cómo se controlaba la persistencia en la versión anterior de J2EE. Cualquier programador que haya trabajado con Hibernate no tendrá ningún problema en utilizar JPA debido a su gran similitud.

Integracion de EJB3 y JSF

Embed Size (px)

Citation preview

Page 1: Integracion de EJB3 y JSF

Integracion de EJB3 y JSF

Integración de EJB3 y JSF

Hace escaso tiempo que salió la versión final de JEE 5, versión que ha traido grandes cambios a la plataforma Java con respecto a la versión anterior. Se ha intentado hacer la plataforma más accesible a los programadores facilitando el desarrollo de las aplicaciones empresariales Java, y tomando como base la configuración por defecto, que tan buenos resultados parece haber generado a la plataforma Ruby on Rails.

A pesar del esfuerzo realizado por el grupo de expertos encargado de definir las especificaciones que forman parte de JEE por simplificar el desarrollo de aplicaciones JEE, hay que tener en cuenta que JEE se trata de una plataforma compleja, alrededor de la cual se concentran usa serie de APIs y de conceptos, y que sin un conocimiento medio de éstos será difícil sacar el máximo partido a JEE, por lo que aunque a primera vista parezca sencillo el desarrollo de aplicaciones tendremos que intentar conocer al máximo todo aquello que se mueve a su alrededor si queremos sacar rendimiento a JEE.

En este artículo/tutorial voy a intentar mostrar cómo desarrollar un prototipo de aplicación en la que integramos dos tecnologías que forman parte de esta renovada plataforma, EJB3 y Java Server Faces. Para ello voy a utilizar NetBeans 5.5, cuyo equipo también ha realizado grandes esfuerzos por simplificar al máximo el desarrollo de aplicaciones JEE con este IDE. La aplicación (si es que la podemos llamar así ) que vamos a desarrollar no podría ser más trivial, y simplemente se encarga de mostrar un listado de los clientes dados de alta en una base de datos, y da la opción de creación de nuevo clientes.

Persistencia

En NetBeans 5.5 tenemos integrado el servidor de aplicaciones open source Glassfish, y éste, a su vez, integra el motor de base de datos open source Derby. Glasshfish tiene configurado vía JNDI un acceso a esta base de datos con el nombre jdbc/__default, que es el que vamos a utilizar para desarrollar este proyecto.

JPA es el nuevo framework de persistencia de Java, y se basa en gran medida en la solución open source más popular de persistencia que hasta ahora hemos tenido, Hibernate. JPA podemos utilizarlo tanto desarrollando con JEE como con JSE, lo cual supone un gran avance con respecto a cómo se controlaba la persistencia en la versión anterior de J2EE. Cualquier programador que haya trabajado con Hibernate no tendrá ningún problema en utilizar JPA debido a su gran similitud.

Iniciando un nuevo proyecto

Para comenzar un nuevo proyecto JEE con NetBeans vamos seleccionar la opción de menú File -> New Project. En la parte izquierda de la nueva ventana seleccionaremos Entreprise y a continuación Enterprise Application. Se nos mostrará un nuevo asistente que deberemos configurar del siguiente modo :

Pulsamos Finish y NetBeans nos va a crear toda la estructura básica de nuestra aplicación. Nos creará un directorio global para el proyecto, y dentro de éste, entre otros, habrá un directorio para el módulo EJB y otro para el módulo Web.

En primer lugar vamos a crear una entidad, que se llamará Cliente. Posteriormente crearemos un Stateless Session Bean para gestionar las posibles operaciones que queramos realizar sobre la entidad Cliente. Con esto ya tendremos configurado nuestro módulo EJB. Dentro de nuestro módulo web implementaremos un Managed Bean que utilizará el Stateless Session Bean tanto para listar como para crear clientes, y crearemos dos páginas web, una para listar los clientes y otra para crear nuevos clientes.

Page 2: Integracion de EJB3 y JSF

Desarrollando el módulo EJB

Entidades

El primer paso es crear una nueva entidad. Java necesita un objeto especial para trabajar con entidades, EntityManager, el cual necesita un fichero de configuración llamado persistence.xml, y en el cuál se configura la conexión a la base de datos. Por lo tanto, cuando creemos a través de NetBeans una entidad, si no se encuentra el fichero persistence.xml NetBeans nos propondrá la creación del mismo.

Para crear la entidad vamos a hacer click con el botón derecho sobre el módulo EJB GestionClientes-EJBModule, y vamos a seleccionar la opción de menú New -> File/Folder. Seleccionamos la categoría Persistence, y en la lista de la derecha hacemos click sobre Entity Class.

Tenemos un nuevo asistente en el que configuraremos el nombre y el paquete de nuestra entidad. En este asistente, una vez hayamos proporcionado el nombre tanto de la entidad como del paquete, nos aparecerá un nuevo botón ( Create Persistence Unit ) en la parte inferior del mismo a través del cual podremos crear el fichero persistence.xml.

El asistente para la creación de la entidad nos quedará del siguiente modo :

Y el asistente para la creación de nuestro fichero persistence.xml nos quedará así :

El Datasource que utilizamos para almacenar nuestras entidades es el que nos propone NetBeans por defecto, que como comentamos anteriormente es un Datasource que viene configurado de serie en Glassfish y hace referencia a una base de datos Derby.

No es necesario que creemos nosotros las tablas manualmente, ya que el nuevo framework de persistencia de Java JPA podemos configurarlo para que cree las tablas en nuestra base de datos a partir de nuestras entidades.

En posteriores artículos intentaré explicar cómo configurar persistence.xml para que almacene nuestros datos en una base de datos MySQL que ya tengamos nosotros creada.

Pulsamos aceptar a los dos asistentes que tenemos abiertos, y modificamos nuestra clase Cliente para implementarla del siguiente modo :

package org.monteagudo.entity;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

/**

*

* @author jlm

*/

@Entity

Page 3: Integracion de EJB3 y JSF

public class Cliente {

private Long id;

private String nombre;

private String apellidos;

private String direccion;

/** Creates a new instance of Cliente */

public Cliente() {

}

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getNombre() {

return nombre;

}

public void setNombre(String nombre) {

this.nombre = nombre;

}

public String getApellidos() {

return apellidos;

}

public void setApellidos(String apellidos) {

this.apellidos = apellidos;

}

Page 4: Integracion de EJB3 y JSF

public String getDireccion() {

return direccion;

}

public void setDireccion(String direccion) {

this.direccion = direccion;

}

}

Stateless Session Bean

Vamos a crear un Stateless Session Bean para poder hacer operaciones sobre la entidad Cliente. Para crear el bean vamos a hacer click con el botón derecho sobre el módulo EJB GestionClientes-EJBModule, y vamos a seleccionar la opción de menú New -> File/Folder. Seleccionamos la categoría Enterprise, y en la lista de la derecha hacemos click sobre Session Bean.

Nos aparece un nuevo asistente para configurar el bean. Lo rellenaremos para que nos quede del siguiente modo :

Como no necesitamos almacenar ningún estado tanto para listar clientes como para crear nuevos clientes, es evidente que nuestro bean va a ser sin estado, por ello en el campo Session Type elegimos Stateless.

En el campo Create Interface podemos elegir Remote, Local o ambas. Si no seleccionamos ninguna, el contenedor generará una interfaz local implícitamente en tiempo de ejecución. El cliente principal de nuestro bean va a ser un Managed Bean del módulo web, es decir, el cliente va a ser una clase que se va a ejecutar en el mismo servidor de aplicaciones, y en la misma JVM, por lo que vamos a seleccionar que nuestro bean implementa una interfaza Local.

Pulsamos Finish, y vemos que NetBeans nos ha creado dos ficheros :

ServicioClientesBean es el bean propiamente dicho que implementa la lógica de negocio, y ServicioClientesLocal es una interfaz con una anotación Local ( si no lleva anotación se asume que es Local ), y que es implementada por nuestro bean.

La interfaz va a quedar definida de este modo :

package org.monteagudo.service;

import java.util.List;

import javax.ejb.Local;

import org.monteagudo.entity.Cliente;

Page 5: Integracion de EJB3 y JSF

/**

* This is the business interface for ServicioClientes enterprise bean.

*/

@Local

public interface ServicioClientesLocal {

public void crearCliente(Cliente cliente);

public List<Cliente> listarClientes();

}

Y el bean quedará definido de este otro modo :

package org.monteagudo.service;

import java.util.List;

import javax.ejb.*;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

import javax.persistence.Query;

import org.monteagudo.entity.Cliente;

/**

* This is the bean class for the ServicioClientesBean enterprise bean.

* Created 16-jul-2006 23:15:44

* @author jlm

*/

@Stateless()

public class ServicioClientesBean implements ServicioClientesLocal {

@PersistenceContext

EntityManager em;

public void crearCliente(Cliente cliente) {

Page 6: Integracion de EJB3 y JSF

em.persist(cliente);

}

public List<Cliente> listarClientes() {

Query query = em.createQuery("SELECT c FROM Cliente AS c");

return query.getResultList();

}

}

Vemos que el bean está anotado como Stateless, lo que identifica al bean como sin estado.

Otra característica importante es la anotación PersistenceContext. Cuando anteriormente creamos la entidad Cliente también configuramos el fichero persistence.xml. Este fichero es el que utiliza el servidor de aplicaciones para crear objetos de tipo EntityManager. Podríamos acceder a estos objetos vía JNDI, pero es recomendado inyectar el EntityManager a través de la anotación PersistenceContext. Una vez tenemos el EntityManager ya vamos a poder realizar operaciones sobre todas nuestras entidades definidas en nuestra aplicación.

Con todo esto ya tendríamos implementado nuestro módulo EJB. Para comprobar si ha ido todo bien podemos hacer un Build de este módulo. Para ello vamos a seleccionar con el botón derecho el módulo del EJB, y vamos a seleccionar la opción Build Project, así veremos si ha habido algún problema con alguna de las clases que hemos definido.

Desarrollando el módulo Web

Antes de comenzar a definir nuestro Managed Bean y nuestras páginas JSF, vamos a configurar un par de cosas en el módulo web.

La primera de ellas va a ser indicar a NetBeans que queremos utilizar JSF. Para ello vamos a hacer click con el botón derecho sobre el módulo web GestionClientes-WebModule, y pulsaremos la opción Properties. En la lista de categorías vamos a seleccionar Frameworks, pulsamos sobre el botón Add y seleccionamos Java Server Faces. Aceptamos, y podremos comprobar que NetBeans, por una parte ha creado el fichero de configuración de JSF, faces-config.xml, y por otra parte ha modificado el fichero web.xml para agregar opciones de configuración de JSF.

La segunda tarea que vamos a realizar a nuestro módulo web va a ser decirle que queremos utilizar las clases que hemos desarrollado en el módulo EJB. Para ello vamos a hacer de nuevo click con el botón derecho sobre el módulo web GestionClientes-WebModule, y pulsaremos la opción Properties. Seleccionamos Libaries y hacemos click al botón Add Project. Seleccionamos GestionClientes-ejb y pulsamos Add Project JAR Files, y después aceptamos.

Ahora ya podemos crear nuestro Managed Bean

Managed Bean

Hacemos click con el botón derecho sobre el módulo web GestionClientes-WebModule y seleccionamos New -> File / Folder. Nos vamos a la categoría web y pulsamos sobre JSF Managed Bean. Nos aparece un asistente para la configuración del Managed Bean, el cuál debemos configurarlo del siguiente modo :

Page 7: Integracion de EJB3 y JSF

El asistente nos crea una plantilla del bean, el cuál modificaremos para implementarlo así :

package org.monteagudo.web;

import java.util.List;

import javax.ejb.EJB;

import org.monteagudo.entity.Cliente;

import org.monteagudo.service.ServicioClientesLocal;

/**

*

* @author jlm

*/

public class ClientesManagedBean {

private Cliente cliente = new Cliente();

@EJB

ServicioClientesLocal servicioClientes;

public Cliente getCliente() {

return cliente;

}

public void setCliente(Cliente cliente) {

this.cliente = cliente;

}

public List<Cliente> getClientes() {

return servicioClientes.listarClientes();

}

public String crearCliente() {

servicioClientes.crearCliente(cliente);

return "success";

Page 8: Integracion de EJB3 y JSF

}

}

Como vemos, podemos inyectar al managed bean un EJB que hemos desarrollado anteriormente en el módulo EJB. Desde entonces podemos utilizar la interfaz como cualquier otra clase dentro del managed bean para crear nuevos clientes y para listar clientes ya existentes.

Páginas JSF

Uno de los últimos pasos que nos queda por realizar es desarrollar dos páginas JSP, así como configurar el fichero faces-config.xml.

Vamos a crear una página que nos va permitir listar todos los clientes existentes en la base de datos. Hacemos click con el botón derecho sobre el módulo web GestionClientes-WebModule y seleccionamos New -> File / Folder. Nos vamos a la categoría web y pulsamos sobre JSP. Nos aparece un asistente para la configuración del JSP en el que únicamente vamos a indicar el nombre de la página web :

Como podemos ver, la plantilla que nos ha creado NetBeans no tiene incluidas los taglib de JSF. Vamos a agregarlos manualmente. Como puede resultar un poco difícil acordarse del uri de los tags, vamos a ver dónde podemos consultarlos de forma más o menos rápida. Navegamos por la ventana de proyectos hasta los ficheros descriptores de los tag libraries (tld) :

Hacemos doble-click sobre el tld y ahí encontraremos las etiquetas short-name y uri, que son las que utilizaremos para agregar las taglibs de JSF.

Una vez tenemos definidos los taglibs que necesitamos, vamos a crear una tabla JSF para listar todos los clientes. NetBeans ofrece una paleta de controles básica que nos permite crear una tabla a partir de una de un objeto java.util.List. Si la paleta de controles no nos apareciera en el IDE podemos mostrarla seleccionando la opción de menú Window -> Palette. En la paleta seleccionamos el control JSF Data Table y lo arrastramos a la zona de código en la que queremos mostrar la tabla. Nos aparece un asistente que nos solicita por una parte el Entity Bean que queremos representar, y por otra parte el método del Managed Bean que nos devuelve la lista de clientes. El asistente lo rellenaremos con la siguiente información :

Como podemos observar, el asistente se ha encargado de generarnos de forma automática la tabla con toda la información referente a nuestra entidad cliente. Finalmente la página la modificaremos para que tenga la siguiente forma :

<%@page contentType="text/html"%><%@page pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%> 

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Listado de Clientes</title></head>

Page 9: Integracion de EJB3 y JSF

<body>

<f:view><h:form><h1><h:outputText value="Listado de Clientes"/></h1><h:dataTable value="#{ClientesManagedBean.clientes}" var="item"><h:column><f:facet name="header"><h:outputText value="Id"/></f:facet><h:outputText value="#{item.id}"/></h:column><h:column><f:facet name="header"><h:outputText value="Nombre"/></f:facet><h:outputText value="#{item.nombre}"/></h:column><h:column><f:facet name="header"><h:outputText value="Apellidos"/></f:facet><h:outputText value="#{item.apellidos}"/></h:column><h:column><f:facet name="header"><h:outputText value="Direccion"/></f:facet><h:outputText value="#{item.direccion}"/></h:column></h:dataTable>

<br/><h:commandButton action="create" value="Nuevo Cliente"/>

</h:form></f:view>

</body></html>

Ahora nos falta crear la página que nos va a permitir crear nuevos clientes. Agregamos la página como hicimos con la anterior, y le daremos el nombre crearCliente. Al igual que en la página listarClientes utilizamos el control JSF Data Table para que el IDE nos generara el código de la tabla, en esta página vamos a utilizar el control JSF Form para que NetBeans nos genere el código del formulario de la entidad Cliente. Para ello vamos a selecccionar el control y lo vamos a arrastrar a la zona de la página en la que queremos implementar el formulario. A continuación nos aparecerá un asistente, el cuál podemos rellenarlo como sigue :

Del formulario que nos ha creado NetBeans vamos a borrar los datos relativos al Id del Cliente, ya que este campo tiene que estar vacío, y será el framework de persistencia JPA quién nos genere el nuevo identificador de cliente.

Por otra parte, he modificado la propiedad value de los campos inputText que ha generado el diseñador, y he utilizado directamente la entidad Cliente en lugar de campos individuales en el Managed Bean. De este modo, es diseñador ha creado lo siguiente :

<h:inputText id="nombre" value="#{ClientesManagedBean.nombre}" title="Nombre" />

Page 10: Integracion de EJB3 y JSF

y lo he cambiado por esto otro :

<h:inputText id="nombre" value="#{ClientesManagedBean.cliente.nombre}" title="Nombre" />

Tampoco hay que olvidarse de agregar dentro del formulario el botón que se encargará de hacer el submit de los datos.

La página, al final, nos tiene que quedar como sigue :

<%@page contentType="text/html"%><%@page pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%> <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%> 

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Nuevo Cliente</title></head><body>

<f:view><h2>Nuevo Cliente</h2><h:form><h:outputText>Nombre:</h:outputText><h:inputText id="nombre" value="#{ClientesManagedBean.cliente.nombre}" title="Nombre" /><br><h:outputText>Apellidos:</h:outputText><h:inputText id="apellidos" value="#{ClientesManagedBean.cliente.apellidos}" title="Apellidos" /><br><h:outputText>Direccion:</h:outputText><h:inputText id="direccion" value="#{ClientesManagedBean.cliente.direccion}" title="Direccion" /><br>

<br/><h:commandButton action="#{ClientesManagedBean.crearCliente}" value="Grabar"/>

</h:form></f:view>

</body></html>

Por último, vamos a hacer una pequeña modificación a la página index.jsp, para que al iniciar la aplicación nos redirija hacia la página listarClientes. Así es cómo debería quedar index.jsp :

<%@page contentType="text/html"%><%@page pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 

<c:redirect url="faces/listarClientes.jsp"/>

Configuración de JSF : faces-config.xml

Lo único que nos queda por hacer antes de probar la aplicación es definir el fichero de configuración faces-config.xml. Para configurar este fichero NetBeans nos provee una sencilla utilidad. Para hacer uso de ella primero tenemos que abrir el fichero faces-config.xml, que se encuentra en la ventana Projects, en el módulo web GestionClientes-

Page 11: Integracion de EJB3 y JSF

WebModule, dentro de la carpeta Configuration Files. Hacemos doble-click para editarlo, y vemos que ya tenemos definido el Managed Bean que habíamos creado.

El siguiente paso es definir las reglas de navegación. Vamos a hacer click con el botón derecho sobre la ventana de código de este fichero, seleccionamos la opción de menú Java Server Faces y a continaución Add Navigation Rule. Hacemos un browse, seleccionamos la página listarClientes y pulsamos Add.

Aviso : A mí, en ciertas ocasiones, se me bloquea NetBeans cuando agrego las reglas de navegación a través del asistente, por lo tanto y por si acaso es conveniente grabar el proyecto antes de continuar. Hay que tener en cuenta que estamos ante una versión beta, por lo que este tipo de cuelgues puede pasar.

Ahora, dentro del código que nos ha generado ( entre las etiquetas navigation-rule ), volvemos a hacer click con el botón derecho, seleccionamos Add Navigation Case, y rellenamos la información que nos solicita el asistente del siguiente modo :

Ya sólo nos faltaría agregar otra regla de navegación para la página crearCliente. Al final, el fichero faces-config.xml nos quedará configurado del siguiente modo :

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

<!-- =========== FULL CONFIGURATION FILE ================================== -->

<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"><managed-bean><managed-bean-name>ClientesManagedBean</managed-bean-name><managed-bean-class>org.monteagudo.web.ClientesManagedBean</managed-bean-class><managed-bean-scope>request</managed-bean-scope></managed-bean>

<navigation-rule><from-view-id>/listarClientes.jsp</from-view-id><navigation-case><from-outcome>create</from-outcome><to-view-id>/crearCliente.jsp</to-view-id><redirect/></navigation-case></navigation-rule>

<navigation-rule><from-view-id>/crearCliente.jsp</from-view-id><navigation-case><from-outcome>success</from-outcome><to-view-id>/listarClientes.jsp</to-view-id><redirect/></navigation-case></navigation-rule>

</faces-config>

Page 12: Integracion de EJB3 y JSF

Probando el Proyecto

Ya sólo nos queda probar que todo funcione correctamente. Para ello vamos a hacer un build del proyecto. En la solapa Projects seleccionamos GestionClientes con el botón derecho y hacemo click sobre build.

A continuación iniciamos la base de datos Derby. Vamos al menú Tools, Derby Database y seleccionamos Start Derby Server.

Y por último seleccionamos de nuevo el proyecto GestionClientes con el botón derecho y clickamos sobre Run Project, y si todo ha funcionado correctamente tendría que abrirse en el navegador la página listarClientes que hemos diseñado anteriormente.

Conclusión

Hemos visto una forma sencilla de trabajar con EJB3 y Java Server Faces con la ayuda de NetBeans. Vemos que la complejidad a la hora de programar se ha reducido bastante con respecto a la versión 2.1 de EJB, pero conviene tener en cuenta que alrededor de todo lo que hemos visto existe un conglomerado de APIs que conviene controlar para poder sacar el máximo partido a JEE.

En esta aplicación hemos trabajado con las configuraciones por defecto que nos propone la plataforma, por lo cual no resulta complejo poner a funcionar este prototipo. Pero no sólo en esto se basa JEE, tenemos servicios y APIs tales como JMS, JTA, Security, Web Services, interceptores, etcétera, que debemos conocer si queremos obtener toda la potencia que JEE nos puede ofrecer.

Page 13: Integracion de EJB3 y JSF

RESTful... la forma más ligera de hacer WebServices (Parte 1)

Quienes hayan usado SOAP para WebService, sabrán que es bien fácil de diseñar, pero algo complicado de consumir: se necesita toda una API para construir los clientes utilizando el WSDL. Por ejemplo, para PHP se necesita de la biblioteca NuSOAP. Entonces, para lograr el concepto de "lenguaje único XML" es un dolor de cabeza. Y más aún si el cliente es tan simple como JavaScript, manejar XML de SOAP provocaría suicidos masivos... o no usar WebServices.

Además, con SOAP se permite crear un solo servicio y ponerle varios métodos. Esto puede llevar a un mal diseño del servicio ya que podría tener un servicio que haga de todo: por ejemplo, un servicio de manejo de Clientes que permita también manejar Proveedores.

RESTful es una propuesta muy interesante de Roy Fielding que permite manejar los servicios web con métodos definidos, manteniendo la simpleza del protocolo como XML, pero que cada servicio sea identificado únicamente con un solo URI.

En este post veremos cómo crear un Servicio RESTful usando NetBeans, y haremos crecer de poco a poco nuestro ejemplo... desde hacer operaciones sencillas, hasta manejar estructuras complejas.

Cabe destacar que los servicios de las redes sociales como Flickr, Twitter, Facebook, etc son basados en RESTful.

Para este ejemplo usaremos NetBeans 6.9.1, y GlassFish v3.0.1, ya que usaremos las características de Java EE6. Con GlassFish v.2 igual funciona, y NetBeans ayuda en ello,

Para comenzar, debemos entender que necesitamos de una clase para manejar un servicio. En esta clase solo pueden haber máximo cuatro métodos públicos que son ejecutados por los cuatro métodos HTTP disponibles para RESTful:

1. GET

2. POST

3. DELETE

4. PUT

Los métodos GET y POST son conocidos en los formularios (<form method="post" />) ¿Tienen algo que ver? Sí, y lo veremos poco a poco. Cada uno de estos métodos determina la acción que hará el REST sobre nuestra aplicación. No deben haber más de un GET o POST o DELETE o PUT, solo tiene que haber uno de cada método. Cada uno tiene una tarea especifica:1. GET: Para obtener un valor. Puede ser un listado de objetos

Page 14: Integracion de EJB3 y JSF

2. POST: Para guardar un nuevo objeto (instancia de identidada) en la aplicación

3. DELETE: Para eliminar un objeto (instancia de identidad)

4. PUT: Para actualizar un objeto.

¿Suena a un mantenimiento CRUD? Sí, exacto. Eso es lo que es: los métodos para hacer mantenimiento a una entidad de la aplicación. Entonces, la clase que deberá tener estos métodos es como una clases EJB Facade  de una aplicación Java EE. Por tanto, esta clase se llamará "Recurso", funcionará como un EJB, solo manejará la persistencia de una etndiad, pero será accedido desde la web. ¿Cómo se hace? Bueno, iremos de poco a poco conociendo cómo hacer un mantenimiento complejo usando únicamente RESTful.CREANDO PROYECTO Y CONFIGURANDO REST

Crearemos un proyecto web común y silvestre en NetBeans. Yo crearé uno llamado SimpleRESTweb. Este proyecto hará un simple cálculo de factorial. (Aunque a muchos no les guste, comenzaré siempre con una calculadora ya que es el clásico ejemplo de Entrada->Procesamiento->Salida.. lo demás, usando entidades, bases de datos, etc.. es lo mismo, solo que utiliza  más variables)

Luego, crearemos una clase común y silvestre, llamada FactorialResource. Tendrá (por ahora) un método llamado factorial()

public class FactorialResource {

public long factorial(long base) { if (base >= 1) { return factorial(base - 1) * base; } return 1; }}

A esta clase se puede crear su TestCase para asegurarnos que funciona correctamente. Notemos que hasta ahora no hemos hecho nada REST. La diversión comienza aquí:

Agreguemos la notación @Stateless al inicio de la clase. Esto convierte automáticamente a nuestra clase en un EJB

Page 15: Integracion de EJB3 y JSF

Luego, seguido al @Stateless agregamos la anotación @Path("/factorial") Esto indica que este recurso será accedido desde la ruta "/factorial" via web. Ahora, guardemos el archivo... y en ese mismo momento, el NetBeans detectará de que se ha creado un recurso REST, entonces pedirá activar esta característica en la aplicación... por tanto pedirá dónde estará activado todos los recursos REST. 

Utilizaremos el dado por defecto (/resources). Clic en Ok.

Nota: En GlassFish v2 (Java EE 5) solo existirán dos opciones

Y con esto, nuestra clase ya es un recurso REST.

Page 16: Integracion de EJB3 y JSF

Pero aún este recurso no tiene métodos. Ahora veremos cómo convertir nuestro método convencional en un método REST.

CREANDO UN MÉTODO REST

Recordemos que solo podemos crear un método de tipo GET,POST,PUT y DELETE. Y como el método factorial nos deberá devolver un solo valor según el parámetro que le especificamos, usaremos el tipo GET.

Para ello agregamos la anotación @GET antes del método.

Y con esto, nuestro recurso ya tiene un método.

Page 17: Integracion de EJB3 y JSF

Antes de continuar, los valores que se reciben desde el recurso REST deben ser objetos. Por tanto, nuestro método debe cambiar un poco para que no devuelva un long, sino un java.lang.String.

Además, debemos indicar que el parámetro base del método Java factorial será recibido via URL con el nombrebase. Es decir, se llamará al URL así

..../factorial?base=5

Para ello usaremos la notación @QueryParam antes de la declaración del parámetro y ponemos el nombre de la cadena query.

@Stateless@Path("/factorial")public class FactorialResource {

@GET public String factorial(@QueryParam("base") long base) {

return Long.toString($factorial(base)); }

long $factorial(long base) { if (base >= 1) { return $factorial(base - 1) * base; } return 1; }}

El nombre del parámetro de la cadena query podría ser diferente al del método java. 

//.... @GET public String factorial(@QueryParam("numero") long base) {//....

Pero si se hace eso, se debería recordar que para accederlo via URL debe ser con ese mismo nombre

..../factorial?numero=5

Pero para evitar problemas, usaremos el mismo nombre. Y en caso de ser necesario, podemos cambiar el nombre. Eso ya queda a criterio del diseñador de la aplicación.

PROBANDO LA APLICACIÓN

Page 18: Integracion de EJB3 y JSF

Pues bien, ahora guardemos el proyecto, hagamos clic derecho sobre el ícono de proyecto y seleccionamos "Deploy". Esperamos a que se compile el proyecto, se ejecute el GlassFish y se despliegue.

Aquí propondré tres maneras de probar el recurso REST. El primero es el más fácil, usando el URL. Bastará con abrir nuestro navegador y escribir el URL del proyecto:

http://localhost:8080/SimpleRESTweb/resources/factorial?base=10

Este URL está compuesto de lo siguiente:

SimpleRESTweb: El contexto de la aplicación. Que generalmente es el nombre del proyecto.

resources: Ubicación de los recursos REST de la aplicación. Este nombre nos lo pidió el NetBeans cuando guardamos la clase Java por primera vez con la notación @Path ya que detectó que tenía recursos REST. Si se desea cambiar esta ruta, hagamos clic derecho en el nodo "RESTful Web Services" del proyecto y seleccionando "REST Resources Configuration"

factorial: Es el nombre de nuestro recurso (Definido por la anotación @Path)

base: Es el parámetro del recurso. Justamente es una cadena Query.

El resultado debe mostrarse tan simple como una web sin formato ni nada

Y ese es el resultado. Quizás me digan "hey, pero esto también lo puedo hacer con un servlet". Pues sí, pero no es lo mismo, ya que el Servlet puede guardar variables de sesión, y aquí en REST no... en Servlet se puede formatear en un HTML, pero aquí en REST no, porque lo que debe devolver es solo dato. 

La segunda manera que muestro cómo probar este recurso REST es usando un formulario HTML. Escribamos lo siguiente en el index.jsp

<body> <h1>Calculando factorial</h1> <form action="resources/factorial"> Base: <input name="base" type="text" />

Page 19: Integracion de EJB3 y JSF

<button>Calcular</button> </form> </body>

El resultado saldrá en otra página. 

Y la tercera forma (que es la más profesional) es usando el NetBeans. 

Hacemos clic derecho sobre el ícono del proyecto y seleccionamos "Test RESTful WebService".

Con esto, el IDE creará una página local que accederá al WADL de la aplicación y se mostrará en el navegador web.

Page 20: Integracion de EJB3 y JSF

El WADL es análogo al WSDL de SOAP

Luego, podemos seleccionar del panel izquierdo el recurso que está disponible (en este caso "factorial")... 

Page 21: Integracion de EJB3 y JSF

... y vemos que nos muestra cuales son los parámetros (solo base) que están disponibles para este recurso. Probamos escribiendo valores en el parámetro, y hacemos clic en "Test".

Page 22: Integracion de EJB3 y JSF

CONSUMIENDO REST

Todo servicio web no es útil si no se sabe cómo consumir. En este post mostraremos cómo consumir este simple REST. En los siguientes post realizaremos recursos que utilizan objetos complejos.

Usando JavaScriptPara consumir desde JavaScript, se debería utilizar la técnica AJAX. Y en vez de hacer toda la biblioteca de consumir AJAX con JavaScript, mejor usamos algo ya hecho... como el jQuery.

Crearemos una página html al que llamaremos test-jquery.html. Y ahí pondremos lo siguiente.

<html>

Page 23: Integracion de EJB3 y JSF

<head> <title></title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"> </script>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <h2>Calcular factorial</h2> Número:<input type="text" name="base" id="base"/> <button type="button" id="calcularBtn">Calcular</button> <div id="resultado"> Resultado: <span></span> </div> <script type="text/javascript"> jQuery("#calcularBtn").click(function(){ var base = jQuery("#base").val(); jQuery.get("http://localhost:8080/SimpleRESTweb/resources/factorial",{ base:base },function(resultado){ jQuery("#resultado span").text(resultado) }) }) </script> </body></html>

Esta HTML funciona desde Firefox cuando se ejecuta desde el NetBeans,

Page 24: Integracion de EJB3 y JSF

y funciona en IExplorer si se ejecuta localmente (o sea, abriéndolo desde el explorador de archivos y activar el filtro de ActiveX que advierte el IE).

Usando JavaCon NetBeans más el complemento Jersey, se nos hace muy fácil consumir servicios REST. Para integrarlo con el IDE, necesitamos registrar el WADL. Esta URL lo podemos obtener así: http://host:puerto/contexto-web/resources/application.wadl

Para nuestro ejemplo, este es

http://localhost:8080/SimpleRESTweb/resources/application.wadl

Podemos abrirlo desde el navegador y se nos mostrará un XML que contiene la definición de los recursos (/factorial) y los parámetros de cada método. En este caso hay un método GET y tiene como parámetro un long.

Page 25: Integracion de EJB3 y JSF

Ahora bien, este URL del WADL lo vamos a necesitar para registrarlo en el NetBeans. En el IDE vayamos al panel de servicios (Ctrl+5) y hacemos clic derecho sobre el nodo "Web Services" y seleccionamos "Add Web Service..."

Luego, en la entrada de URL, pegamos la dirección del WADL. Y como nombre de paquete ponemos simplerest. 

Page 26: Integracion de EJB3 y JSF

Y listo, ya tendremos registrado el WebService en nuestro IDE. 

Esto nos permitirá utilizar este servicio en cualquiera de nuestras aplicaciones. Por ejemplo, ahora, en Java.

Hagamos un nuevo proyecto llamado SimpleRESTClientJavaApp.

Ahora, crearemos un nuevo archivo (Ctrl+N) y seleccionamos la categoría "Web Services" y el tipo de archivo "RESTful Java Client"

Page 27: Integracion de EJB3 y JSF

Luego, en el siguiente paso, pongamos como nombre de la clase FactorialClient, dentro de la opción "Select the REST resource" seleccionemos la opción "IDE Registered" 

Page 29: Integracion de EJB3 y JSF

y clic en "Finish". Listo, el IDE nos creará la clase FactorialClient que contendrá los recursos necesarios para acceder al servicio REST.

Ahora, ¿cómo se consume esto?... en nuestra clase Java solo debemos instanciar la clase, pasarle el parámetro y recibir el valor. Fácil