Ejemplo de aplicación Java EE 6.
Tienda Web con JPA+EJB+JSF

FJRP - CCIA-2011


Date: Septiembre-2011



Índice General

Descripción de la aplicación de ejemplo

Presentación del ejemplo

Como punto de partida para el desarrollo del proyecto Java EE del curso 2011/12 se aporta como ejemplo una pequeña aplicación para la gestión de una tienda web.

Se trata de una aplicación Java EE 6 Cuenta una capa de aplicación (o negocio) implementada con componentes EJB (Enterprise Java Bean) que hace uso de JPA (Java Persistence API) como mecanismo de mapeo Objeto/Relacional para proveer de una capa de acceso a la base de datos.

Se incluyen 2 capas de presentación diferentes:

Pasos previos

  1. Instalar el entorno de desarrollo Netbeans 7.0.1 y el servidor de aplicaciones GlassFish v3.1.1

    Es recomendable trabajar con una versión de Netbeans lo más reciente posible (actualmente Netbeans 7.0.1).

    Se puede descargar la última versión de Netbeans en http://www.netbeans.org asegurándose de que incluya el servidor de aplicaciones GlassFish.

    La instalación de Netbeans y Glassfish se hace de forma conjunta quedando Netbeans configurado para usar GlassFish como servidor de aplicaciones por defecto.

    En el laboratorio no se requieren permisos de administrador para instalarlo y debería ser posible mantener a la vez la versión existente junto con la nueva.

  2. Instalar la base de datos. Los datos manejados por la aplicación de ejemplo se almacenan en un servidor MySQL.

    Descarga: Tablas+datos (ejemplo-JEE.sql)

    Instalación:

  3. Antes de desplegar y ejecutar la aplicación es necesario incluir en el servidor de aplicaciones el conector JDBC de MySQL.

    Se puede usar el fichero mysql-connector-java-5.1.XX-bin.jar incluido en Netbeans o descargarlo desde la página de MySQL.

          $ cp /home/alumno/netbeans-7.0.1/ide/modules/ext/mysql-connector-java-5.1.XX-bin.jar \
               /home/alumno/glassfish-3.1.1/glassfish/domains/domain1/lib/
    

  4. Abrir la aplicación en Netbeans La aplicación Java EE de ejemplo está conformada por tres proyectos Netbeans:

    Los dos primeros están agrupados en un proyecto Java EE $ \to$ Enterprise Application y se desplarán juntos en el servidor de aplicaciones. Se deberá abrir el proyecto

    Descarga: ejemploTiendaWeb.tar.gz

          $  tar xzvf EjemploTiendaWeb.tar.gz
    

    Al abrir el proyecto EjemploTiendaWeb se carga sólo el proyecto principal. Es necesario seleccionar la opción Open Requierd Projects en la opción Open Project antes de abrirlo o en el menú contextual del proyecto una vez abierto ([botón derecho] $ \to$ Open Requierd Projects), aparecerán 2 subproyectos:

    En caso de que Netbeans informe del error, se deberá especificar el servidor de aplicaciones a utilizar, en este caso la versión 3.1 de GlassFish.

  5. Compilación, despliegue y ejecución.

    Desde la pestaña services de Netbeans se puede manejar el servidor de aplicaciones GlassFish (Servers$ \to$GlassFish v3 domain: iniciar, parar, recargar) y ver la lista de aplicaciones deplegadas.

    También se puede acceder a la consola de GlassFish desde un navegador web con la url: http://localhost:4848

Arquitectura de la solución de ejemplo

El ejemplo de aplicación Java EE 6 sigue un esquema de cliente ligero estricto. Tanto la capa de presentación web basada en JSF como la aplicación de escritorio SWING no implementan ningún tipo de lógica de aplicación, limitándose a mostar datos al usuario y a capturar y validar las entradas recibidas. Toda la lógica de la aplicación necesaria para implementar los caso de uso del ejemplo es responsabilidad de los componentes EJB incluidos en el subproyecto EjemploTienda-ejb.

Image esquemaPractica

En este caso, al tratarse de una aplicación sencilla, esta arquitectura tan estricta puede ser un poco excesiva y en el caso de que sólo se hubieran incluido clientes web se podría hacer conseguido la misma funcionalidad trabajando exclusivamente en el contenedor de Servlet, con JSF y los Managed Beans. En este caso, la razón de incluir una capa de EJBs (y por lo tanto exigir un servidor de aplicaciones JEE completo) es la de permitir el acceso remoto desde la aplicación SWING.

Simplificaciones

Capa de lógica de aplicación

El proyecto EjemploTiendaWeb-ejb contiene la definición de las Entidades JPA responsables del mapeo Objeto/Relacional de la base de datos y los EJBs responsable de implementar la lógica de los casos de uso de la aplicación.

Entidades JPA

El paquete entidades contiene la definción de las clases Entidad del ejemplo, junto con las enumeraciones TipoUsuario y EstadoPedido.

Todas las entidades ($ \equiv$ tuplas) están identificadas por atributos numéricos gestionados por MySQL (campos autoincrementales), no se utilizan atributos de las entidades como identificadores (NIF, etc).

Entidades

Usuario.
Almacena los datos de los usaurios del sistema (login, password, tipo, fecha de alta, fecha de último acceso). Se usa principalmente para el control de accesos.
Cliente.
Almacena los datos personales de los usuarios de tipo cliente.
Producto.
Almacena los datos de los productos que conforman el catálogo de la tienda.
Familia.
Almacena las descripciones de las familias de productos consideradas en el catálogo de la tienda.
Pedido.
Almacena la información de los pedidos (fecha, cliente, estado)

LineaPedido.
Almacena la información de una línea de un pedido.

Enterprise Java Beans

Los EJB que conforman la capa modelo y son responsables de la lógica de la aplicación se reparten en dos paquetes (ejb.dao, ejb.negocio). En ambos caso se ofrece tanto un interfaz local (usado por la aplicación Web JSF) como un interfaz remoto (usado por la aplicación de escritorio SWING).

Hay un tercer paquete (ejb.excepciones) con la definición de las excepciones generadas por la capa modelo: ExcepcionEntidad (error en el acceso a una entidad de la B.D., uso de un ID que no existe, inserción de un ID repetido, etc), ExcepcionExistencias (intento de servir un producto del que no hay stock disponible)

Paquete ejb.dao

El paquete ejb.dao provee de EJBs para implementar las operaciones básicas sobre las entidades que componenen la aplicación (con la excepción de la entidad LineaPedido que es gestionada por el EJB PedidoDAO).

La funcionalidad ofrecida por este conjunto de EJB se coresponde de un modo genérico con el patrón DAO (Data Access Object), que oculta las tecnologías y el modo de acceso a los datos, delegando, en este caso, las operaciones concretas en el EntityManager de JPA.

En esta caso se ha definido un DAO genérico (GenericoDAO [implementación] y GenericoDAOInterface [inetrface]) con las 4 operaciones básicas (crear, buscar por ID, actualizar y borrar). De esta clase genérica (junto con el respectico interfaz genñerico) heredan los demás EJBs (y sus interfaces local y remoto), añadiendo nuevas operaciones, usualmente operaciones de búsqueda específicas.

GenericoDAO.
Operaciones básicas sobre las entidades (independientes de la Entidad concreta)
UsuarioDAO.
Operaciones sobre Usuarios. Incluye operaciones de autenticación y comprobación de privilegios.
ClienteDAO.
Operaciones sobre Clientes. Añade diversos tipos y criterios de búsqueda.
ProductoDAO.
Operaciones sobre Productos. Añade diversos tipos y criterios de búsqueda, incluida la búsqueda por familia.
FamiliaDAO.
Operaciones sobre Familias. Añade diversos tipos y criterios de búsqueda.
PedidoDAO.
Operaciones sobre Pedidos (e implicitamente sobre LineaPedido). Añade diversos tipos y criterios de búsqueda y la operación anularPedido(), que marca un pedido como anulado y reincorpora las candidades pedidas a las existencias de los productos devueltos.

Paquete ejb.negocio

En este paquete se incluyen EJBs que implementan caso de uso específicos de la aplicación. En general proveen de operaciones de mayor complejidad que las del paquete ejb.dao, responsabilizándose de coordinar las invocaciones de otros EJBs encargados del manejo de datos. En este caso se implementa un patrón Service Facade puro.

CatalogoService.
EJB sin estado responsable de la gestión del catálogo de productos, realizando búsquedas de productos y familias bajo diversos criterios. Delega sus tareas en los EJBs ProductoDAO y FamiliaDAO
CompraService.
EJB con estado responsable de la gestión del carro de la compra de un cliente.

Nota: No es estrictamente necesario utilizar un EJB con estado en este caso (además de ser poco escalables), se incluye para mostar su uso.

GestorUsuariosService.
EJB sin estado resposable de la autenticación y de la gestión de usuarios y clientes (creación de nuevos Clientes, junto con le alta de su respectivo Usuario, y modificación de los datos del cliente)

Capa de presentación Web

La capa de presentación Web se ha implementado utilizando el framework JSF(Java Server Faces 2.0). Se ha empleado Facelets como tecnología para la definición de las vistas en lugar de páginas JSP(Java Server Pages), en primer lugar por ser la tecnología por defecto para JSF 2.0 y por la facilidaes que ofrece para definir y manejar plantillas.

Las responsibilidades de la capa web basada en JSF se distribuyen entre tres componentes:

Páginas JSF

Todas las páginas JSF que conforman la aplicación comparten la misma plantilla (definida en el fichero plantillas/plantillaGeneral.xhtml conforme a la sintaxis de los Facelets).

Cada una de las páginas JSF que componen la aplicación define su propia zona de contenido.

Managed Beans

En el ejemplo se definen tres Managed Beans dentro del paquete controladores. Todos ellos tienen alcance de sesión (@SessionScoped), por lo que sus atributos estarán disponibles mientras dure la sesión del usuario (o hasta que esta caduque). El seguimiento de la sesión es responsabilidad del servlet JSF, el programador simplemente debede declarar el tipo de alcance.

Los Managed Beans de la aplicación de ejemplo delegan toda su funcionalidad en los EJBs de la capa de aplicación (subproyecto EjemploTiendaWeb-ejb) por lo que sus únicas funciones estan relacionadas con la gestión de las interacciones derivadas de la acción del usuario:

Todos los Managed Beans heredan de la clase BaseController que ofrece una serie de funcionalidades básicas comunes a todos los controladores:

Managed Beans de la capa web del ejemplo

CatalogoController.
Gestiona las interacciones relacionadas con el catálodo de productos de la tienda (búsqueda de productos, navegación por familias, presentación de detalles del producto)

CarroCompraController.
Gestiona las interacciones relacionadas con el mantenimiento del carro de la compra del cliente.

UsuarioController.
Gestiona las interacciones relacionadas con la autenticación de usuarios y la gestión del perfil del cliente.

En los métodos de los Managed Benas vinculados a acciones de las páginas JSF (atributo action en enlaces [h:commandLink] y botones [h:commandButton]) se ha seguido la convención de que sus nombres comiencen por el prefijo do. Por ejemplo:

Capa de presentación SWING

(pendiente de completar)



ribadas 2011-09-20