miércoles, 19 de junio de 2013

Fin del curso. Videos. Creando una aplicación Java EE 6 completa paso a paso.

Este vídeo es una demostración de cómo emplear la plataforma Java EE 6 para desarrollar una aplicación web completa. Se trata de un catálogo de artículos cuyo nombre y precio están almacenados en una base de datos. Asimismo, las compras quedan registradas en la base de datos junto con los datos del cliente y la relación de artículos comprados. A mayores, se implementa un servicio web RESTful y un Timer para mostrar su funcionamiento. 

Muchos de los aspectos tratados en el vídeo han sido vistos en clase; algunos, en cambio, son novedosos. Trata de identificar todos ellos y de profundizar en el conocimiento de la plataforma.  A modo de repaso general podrías intentar implementar como proyecto final del curso una tienda similar. 

 

 

Estructura de la aplicación, con todos sus componentes enumerados.

 

01:35    Características de las aplicaciones empresariales
03:21    Qué se necesita para construir una aplicación empresarial
04:15    Arquitectura de una aplicación empresarial
06:47    Herramientas empleadas para construir la aplicación de ejemplo
09:20    Creación del proyecto mediante Maven
10:47    Activación de JSF en el servidor JBoss
11:38    Instalación de CDI (Contexts and Dependency Injection) y facelets
12:49    Se muestra en el árbol del proyecto el archivo beans.xml (creado al activar CDI) y faces-config.xml (creado al activar JSF y facelets)
14:34    Se añade una plantilla JSF al proyecto web
15:55    Se crea index.xhtml como faces composite
17:39    Se crea la clase "Product", que posteriormente será declarada como entidad
18:23   Creación del bean "ProductsBean" (etiquetado para inyectar dependencias como @named)
20:30    Edición de index.xhtml para incluir una tabla de artículos.
23:20    Activación de la persistencia.
25:19    Se declara la clase Product como entidad de persistencia y se crea un campo clave 'id'
26:21    Se crea el EJB ProductDao (DAO de Data Access Object) que se encargará de las operaciones de persistencia de la entidad Product.
30:23   Declaración de un atributo en "ProductsBean" en el que se inyectará una instancia del EJB ProductDao.
34:19    Se crea un EJB singleton "TestDataGenerator" para generar directamente algunos productos y así poder probar la aplicación sin tener que hacer inserciones previas en la base de datos.
38:20     Se añade una columna más a index.xhtml para albergar una imagen asociada al producto.
40:20     Se sustituye la consulta original para listar los productos por una consulta basada en la clase CriteriaBuilder
44:41    Se nos muestra cómo usar la herramienta Arquillian para hacer pruebas unitarias a los componentes EJB basadas en aserciones.
54:29    Se empieza a reestructurar el código de "ProductDao" para conseguir que haciendo clic en el precio del producto se pueda alternar entre una ordenación ascendente o descendente de la lista de productos por el campo de precio.
58:14    Se crea el link en el facelet index.xhtml para la ordenación ascendente/descendente por precio.
60:14    Se crea un parámetro de entrada al facelet index.xhtml para controlar el tipo de orden.
61:57    Creación de un nuevo facelet "details.xhtml" para visualizar los detalles del artículo cuando se hace clic en el nombre.
62:23    Se crea un nuevo bean para dar soporte a los detalles del producto llamado "ProductDetailsBean"
64:47    Se crea un parámetro de entrada al facelet details.xhtml que almacenará el id del artículo al que se ha hecho clic junto con un evento para que ProductDetailsBean busque los datos del producto en la base de datos en cuanto se reciba dicho parámetro.
66:16    Se crea el link en el nombre del producto en index.xhtml
69:27    Se empieza a preparar ProductDao para que sea capaz de filtrar las búsquedas de productos ya que se va a incluir un cuadro de texto en el facelet principal para hacer filtrados.
70:50    Se crea el cuadro de texto para el filtro en el facelet y un botón para activarlo.
73:50    Sustitución del botón por el empleo de AJAX
75:35    Se crea el EJB que dará soporte a la cesta de la compra, "Basket.java"
80:36    Se crea el facelet checkout.xml donde el cliente introducirá sus datos antes de confirmar la compra
81:23    Se introduce la clase "Customer" que será la entidad que dé soporte a los datos del cliente.
82:42    Se crea el EJB "OrderProcessor" que se encargará de las operaciones de persistencia relativas a la orden de compra.
83:12    Se crea la entidad "WebOrder" para dar soporte al pedido.
85:35    Se declaran referencias inyectadas a Customer y a la lista de productos del pedido en el EJB Basket
85:54    Se crea un evento en Basket para que sea lanzado cada vez que se confirma un pedido que incluya una referencia a WebOrder.
91:35    Se inician los procesos para validar los campos del cliente.
98:10    Se crear la clase OrderSMSNotifier con la que se nos explicará cómo tratar las tareas asíncronas
106:12   Creación de un Timer de ejemplo.
110:40   Creación de un servicio web RESTful para acceder a los productos de la base de datos.

 

jueves, 13 de junio de 2013

Diapositivas. Clase 14: módulo transversal sobre Gestión de la Innovación

Ejercicios de clase. Clase 13: creando servicios RESTful paso a paso sin asistentes.

Sigue estos dos tutoriales, para crear y consumir sevicios web RESTful sencillos pero, a diferencia del ejercicio anterior, sin valerse de los potentes asistentes de NetBeans, sino desarrollando el proceso paso a paso:

Ejercicios de clase. Clase 13: creando un servicio web RESTful para consultar una base de datos.

Aprovechando la base de datos bdChat creada en un ejercicio anterior, crea un servicio RESTful mediante la opción del asistente de NetBeans para crear servicios RESTful a partir de bases de datos.


Para exponer la base de datos al servicio web sigue estos pasos:




1. Sigue los pasos habituales para crear una aplicación web. No es necesario emplear JSF.

2. Vete a File>New File... y en el apartado Web Services selecciona RESTful Web Services from Database.

3. Añade la única tabla que habíamos creado en la base de datos bdChat (POST) y deja toda la configuración por defecto tal y como se va presentando en el asistente.


Para probar el servicio una vez creado, sigue los siguientes pasos:


1. Hacer clic con el botón secundario del ratón sobre el nombre del proyecto y seleccionar "Test RESTful Web Services"

2. En el cuadro de diálogo emergente cambia la selección a Web Test Client in Project y haz clic en el botón Browse...

3. Marca ServiciosRESTful y pulsa en OK.

4. Se abrirá automáticamente una web de testeo en nuestro navegador donde podemos probar distintas operaciones. Por ejemplo, en la figura se ha hecho un GET sin argumentos para obtener todas las entradas de la tabla del chat; en este caso, sólo tiene una entrada con Id 152 como podemos observar en el código XML de respuesta.




Ejercicios de clase. Clase 12: creando una operación de servicio web SOAP simple

Una vez implementado el servicio se puede probar directamente desde NetBeans, aunque no tengamos un cliente todavía.

En el testeo podemos comprobar que el tipo y el valor de los argumenos y resultados es el correcto, además de todo el código XML de los mensajes SOAP de solicitud y respuesta.

La aplicación cliente invoca el servicio para calcular el cuadrado de un valor constante.

 

 Crea un servicio dentro de un proyecto web que implemente la operación cuadrado() para elevar al cuadrado el número real que se le pase como argumento. Despliégalo en el servidor GlassFish y después crea una aplicación de escritorio que consuma el servicio actuando como cliente. El cliente simplemente mostrará en la consola el resultado de aplicar la operación del servicio a un valor constante. Para realizar el ejercicio puedes apoyarte en la referencia visual paso a paso que te proporcionan estos dos tutoriales de ejemplo: el primero, para crear el servicio web y el segundo para construir la aplicación cliente.





Diapositivas. Clase 12: servicios web


Ejercicios de clase. Clase 12: definición y uso de estereotipos

Los estereotipos, básicamente, nos permiten agrupar conjuntos de anotaciones bajo otra anotación única. En la definición del estereotipo hay que indicar qué anotaciones lo constituyen y luego sólo hay que anotar las clases con el nuevo estereotipo como si, en realidad, estuviesen anotadas con todas y cada una de las anotaciones que conforman el estereotipo.

 

1. El asistente de NetBeans para crear nuevos archivos permite definir rápidamente un estereotipo.

2. Al nombre del estereotipo se van a vincular todas las anotaciones que se incluyan en la definición del mismo. La declaración de estereotipo siempre va precedida de la anotación @Stereotype.

3. Los beans anotados con el nuevo estereotipo tiene una apariencia más limpia, al sustituir todas las anotaciones por un único estereotipo.

Ejercicios de clase. Clase 12: ejemplo de definición y uso de un Interceptor Binding

Los Interceptor Bindings son un mecanismo que nos permite aplicar clases Interceptor a los métodos de los beans de un proyecto web, tal y como hemos visto para los EJB. Cuando creamos un tipo Interceptor Binding, su nombre genera una nueva anotación del tipo @nombreDelInterceptorBinding que será aplicada tanto a la clase Interceptor como a la clase del bean interferido, vinculándolas. De esta manera, el Interceptor podrá hacer pre y post procesamiento a los métodos del bean siguiendo el paradigma de la programación orientada a aspectos. 

 

1. Con el asistente de NetBeans podemos crear rápidamente un nuevo tipo Interceptor Binding

2. El la definición del tipo vamos a encontrarnos con la anotación @InterceptorBinding
3. Debemos añadir la anotación con nuestro nombre del Interceptor Binding a la clase Interceptor. En el ejemplo, como el Interceptor Binding se llama LogginIterceptorBinding, la anotación será @LogginIterceptorBinding.
4. Al igual que el punto anterior, hay que anotar con @LogginIterceptorBinding la clase del bean cuyos métodos van a ser interceptados por la clase Interceptor (LogginInterceptor)
5. En el archivo de configuración beans.xml debemos declarar los interceptores que vayamos a desplegar en el servidor.
6. Al ejecutar la aplicación e invocar a uno de los métodos del bean vemos cómo efectivamente el interceptor ha conseguido escribir información antes y después de su ejecución en la  consola del servidor GlassFish

Ejercicios de clase. Clase 11: implementando un Timer

Los métodos de los EJB pueden ser etiquetados con @Schedule para que sean invocados en intervalos regulares de tiempo. La sintaxis empleada para especificar esa periodicidad es similar a la de cron de UNIX. Puedes consultarla aquí

 

El método myTimer() se ejecutará cada 10 segundos imprimiendo en la consola del servidor la hora del sistema. El atributo persistent si se establece a "true" hace que el Timer se guarde después de un reinicio o una caida del servidor para que continúe invocándose nada más ser reiniciado.
Puedes descargar el código de las clases NewTimerSessionBean y su auxiliar ServicioHora aquí

Salida del Timer de ejemplo en la consola del servidor GlassFish, ejecutándose cada 10 segundos


Ejercicios de clase. Clase 11: implementando un Interceptor

Un Interceptor es una clase especial que dispone de un método que es ejecutado cuando se  invoca un método de un EJB, bien porque el método invocado está anotado específicamente para ser interceptado o bien porque la clase entera está anotada para ser interceptada, de manera, que este hecho afectará a todos sus métodos. En resumen, los Interceptors permien hacer procesamientos anteriores y posteriores a la ejecución de un método de un EJB.

Clase correspondiente a un Interceptor. El método tiene que ser anotado con @AroundInvoke y debe respetar la signatura mostrada en la figura, aunque su nombre es indiferente. El parámetro context encapsula todos los metadatos correspondientes a la clase y el método interferidos. Así, en este ejemplo, se emplea el parámetro de tipo InvocationContext para imprimir el nombre del método interferido. El método proceed() permite ejecutar el método interferido, por lo que todo el código anterior corresponde a preprocesamiento y el posterior a postprocesamiento.

Puedes descargar el código de InterceptorSimple aquí
Puedes acceder a la API de la clase InvocationContext aquí


Por su parte, el componente intercepado, tiene que ser anotado con @Interceptors para indicar qué clases de tipo Interceptor tiene asociadas
Esta es la salida generada por el interceptor de ejemplo en la consola del servidor GlassFish cuando es interceptado el método onMessage() del EJB NewMessage.


miércoles, 12 de junio de 2013

Ejercicios de clase. Clase 11: ejemplo de CDI, qualifiers e interceptor binding.

Saludo formal empleando inyección de dependencias

Saludo informal empleando un qualifier

 

Crea una aplicación web JSF que disponga de un sencillo formulario con un cuadro de texto (inputText) donde el usuario pueda escribir su nombre, un botón (commandButton) para enviar el formulario etiquetado como "Salúdame" y un cuadro de salida (outputText) para mostrar un saludo. Al pulsar el botón se invocará a un método de un bean que mostrará la salida en el outputText del formulario, consistente en un saludo al usuario de la forma ¡Hola, <nombreUsuario>! El bean tendrá dos propiedades: el nombre de usuario de tipo String y el saludo, que no será de tipo String, sino que pertenecerá a una clase Saludo con un método String getSaludo(String nombreUsuario) para obtener el String del saludo.

 

Descarga de la solución a los apartados 1 y 2 (proyecto NetBeans para GlassFish) 

Descarga de la solución a los apartados 3 y 4 (proyecto NetBeans para GlassFish)

 

  1.  Esta instancia de la clase Saludo ha de ser inyectada mediante CDI en el bean.
    Tanto el bean como la clase Saludo están anotadas con @Named. Por otra parte, la declaración de la referencia a la instancia de la clase Saludo es anotada con @Inject

  2. Crea un clase derivada de Saludo, SaludoInformal, que sobreescriba el método getSaludo() cambiando el saludo que devuelve por ¡Ey, <nombreUsuario>! Crea un qualifier @Informal para que pueda ser injectada la clase derivada en lugar de la clase base en el campo del bean.
    Creando un qualifier "Informal" asociado a la clase derivada de Saludo, SaludoInformal, podemos anotar la referencia original con @Informal para indicar que se quiere inyectar una instancia de la clase derivada (SaludoInformal) a pesar de tratarse de una declaración de atributo del tipo Saludo (la clase base)

  3. Crea un Interceptor Binding que cada vez que se llame a getSaludo() escriba a la entrada al método "Llamando a <método> con argumento <nombreUsuario>" y que escriba a la salida "Saliendo de <método> con valor de retorno <saludo>"

  4. Crea un estereotipo que permita sustituir el uso de las anotaciones @Named y
    @RequestScoped por una única anotación. Aplica el estereotipo a las clases Saludo y SaludoInformal. 

     

Diapositivas. Clase 11: Transacciones en EJBs

Las transacciones manejadas por el contenedor EJB soportan distintos valores para su anotación @TransactionAttribute:

  •     TransactionAttributeType.REQUIRED: se trata del valor por defecto si no se emplea la anotación para indicar el atributo transaccional. Se interpreta como que el método anotado con este valor tiene que ser ejecutado dentro de una transacción. Más especificamente, cuando existe una transacción activa y el método es invocado desde esa transacción, automáticamente entra a formar parte de la misma. Si por el contrario, es invocado desde un contexto no transaccional, se crea una nueva transacción para ejecutar el método. En caso de fallo, cuando se revierte la transacción, el rollback siempre afectará a los métodos anotados como "REQUIRED".
    Supongamos que antes de llamar a crearDetalleEmpleado() para crear un ojbeto DetalleEmpleado se crea un objeto Empleado general. Tanto si se produce un error antes como después de haber creado un objeto DetalleEmpleado con la llamada a crearDetalleEmpleado(), el objeto DetalleEmpleado jamás se construirá porque la operación entra a formar parte de la transacción original de crearEmpleado(), de tal manera que si ya hubiera sido instanciado se revertirá la operación y se eliminará la instancia.
  •     TransactionAttributeType.REQUIRES_NEW: implica que siempre se creará una nueva transacción para el método anotado con este valor de atributo independientemente de si se invoca desde un contexto transaccional o no.
    Supongamos que se crea un objeto Empleado antes de invocar a crearDepartamento(). Al invocar a crearDepartamento() se crea una instancia de Departamento que posteriormente será encapsulada en el objeto Empleado. Si se produjese algún fallo en el método crearEmpleado() justo después de la llamada a crearDepartamento(), la instacia de Departamento no se eliminaría porque ha sido creada en una transacción independiente a la de crearEmpleado() que ha culminado con éxito.
  •     TransactionAttributeType.SUPPORTS: supone la propagación del estado transaccional del contexto que invoca al método anotado con este valor. Esto es, si el método es invocado desde una transacción activa, entonces entrará a formar parte de esa transacción y también se verá afectado por el rollback en caso de fallo. En cambio, si el método es invocado normalmente, sin un contexto transaccional, entonces su código también se ejecutará normalmente sin formar parte de ninguna transacción.
  •     TransactionAttributeType.NOT_SUPPORTED: se emplea en situaciones donde determinadas tareas no pueden ejecutarse dentro de una transacción. Así, si el método anotado con este valor de atributo es invocado desde una transacción activa, la transacción es pausada justo antes de la invocación del método y reanudada tras su ejecución. En caso de una invocación desde un contexto no transaccional, el método se ejecutará normalmente fuera de cualquier transacción.
    El ejemplo más ilustrativo de operaciones que no pueden ser incluidas en una transacción es el envío de un email, por tratarse de una tarea de naturaleza asíncrona. En este caso, la operación de registro del usuario debe ser pausada antes de enviar el email y reanudada justo después, pero en ningún caso el envío del email entra a formar parte de la transacción de registerUser()
  •     TransactionAttributeType.MANDATORY: sirve para asegurarse de que el método anotado con este valor va a ejecutarse dentro de una transacción pero a diferencia de otros valores del atributo lanza una excepción si es invocado desde un contexto no transaccional.
    Si llevamos a cabo una transferencia de capital que supone dos operaciones: deducir el capital de una cuenta origen y añadirlo a una cuenta destino, ambas operaciones deben necesariamente ejecutarse formando parte de una transacción; en caso contrario, se lanzará una excepción.
  •     TransactionAttributeType.NEVER: se emplea en raras ocasiones. Permite que cuando desde una transacción activa se invoca un método anotado con este valor de atributo, automáticamente se lance una excepción.

Ejercicios de clase. Clase 10: aplicación web de noticias (EJB Message-Driven + EJB de sesión Singleton + JPA + Servlets)

 

Sigue los pasos del proyecto propuesto por la documentación de NetBeans Creating an Enterprise Application with EJB 3.1 consistente en una sencilla aplicación web que permite añadir noticias (título + contenido) a un listado que se almacena en una base de datos. Asimismo, dispone de un contador para saber en cada momento el número de sesiones abiertas. La aplicación dispone de los siguientes elementos:

 

  • Una clase de entidad NewsEntity para soportar la persistencia de las noticias.
  • Un EJB Message-Driven llamado NewMessage que se encarga de leer los mensajes que uno de los servlets (PostMessage) va depositando en una cola gestionada por JMS, para luego guardarlos en la base de datos.
  • Una clase abstracta AbstractFacade y una clase derivada de ella, NewsEntityFacade, que nos proporciona una instancia de EntityManager para permitir las operaciones habituales sobre la base de datos a nuestra clase entidad.
  • Un EJB de sesión singleton, SessionManagerBean, que actúa como escuchador de los eventos de creación y destrucción de sesiones para mantener actualizado un contador. (Los beans de sesión singleton son una novedad en EJB 3.1 así como que se permita que este EJB esté incluido en el módulo web en lugar de situarse en el módulo EJB)
  • Un servlet ListNews que genera la interfaz principal de la aplicación donde se muestra el listado de las noticias almacenadas actualmente, un enlace que nos lleva a comunicarnos con otro servlet (PostMessage) para añadir una noticia nueva y el número de sesiones abiertas actualmente.
  • Un servlet PostMessage que se encarga de mostrar el formulario para que el usuario pueda enviar una nueva noticia al servidor. El modo de envío es asíncrono, agregándolo a la cola de mensajes que el EJB Message-Driven luego irá procesando.
(Puedes descargar el proyecto empleando el enlace de la propia documentación)


Ejercicios de clase. Clases 9 y 10: Ampliar la funcionalidad del chat

A partir de la solución al ejercicio anterior de implementar un chat empleando un EJB de sesión, amplía su funcionalidad habilitando en la interfaz del cliente un botón "Eliminar mensajes" que sea capaz de borrar todos los mensajes que se hayan guardado hasta ese momento en la base de datos.

Pasos:


  • Inserta un nuevo botón en la interfaz gráfica del cliente para eliminar los mensajes.  

  • Añade a la interfaz remota un nuevo método para que el cliente pueda solicitar al EJB que vacíe la tabla de mensajes.
  • El manejador del evento Action debe ahora invocar el método de la interfaz para borrar los mensajes valiéndose de la referencia al bean que ya había sido empleada con anterioridad para listar y enviar mensajes. Además limpiará el área de texto donde se visualizan todos los mensajes.
  • En la clase entidad Post debe declararse una nueva consulta con nombre que permita borrar todos los registros de la tabla correspondiente.
  • El bean tendrá que implementar el método de borrado de la interfaz remota valiéndose de la referencia al EntityManager que ejecutará la consulta con nombre de la entidad que creamos en el apartado anterior.


martes, 11 de junio de 2013

Ejercicios de clase. Clase 9: aplicación de escritorio + EJB de sesión + JPA

 

Crea una aplicación Java EE para que múltiples usuarios se puedan comunicar y que sus mensajes queden almacenados en una base de datos. La aplicación constará de:

  • Una GUI Java Swing actuando como cliente desde la que los usuarios pueden introducir su nombre y enviar mensajes. Cada vez que el cliente envíe un mensaje podrá ver la lista de mensajes ya almacenados, precedidos del nombe del usuario que los ha enviado.

  • Un EJB de sesión que manejará la persistencia.

  • Una tabla en una base de datos Java donde se almacenará un identificador, el nombre de usuario y el contenido de cada mensaje enviado. El identificador se generará de forma automática y actuará como campo clave. La longitud máxima de los mensajes será de 2000 caracteres.

     

     

jueves, 6 de junio de 2013

Ejercicios de clase. Clase 8: dar persistencia a los datos de un conjunto de personas.




 

Siguiendo el mismo esquema del ejemplo que se enlaza al final del post anterior, crea el soporte necesario para dar persistencia a los datos de una persona (Id/DNI, Nombre, Primer Apellido, Segundo Apellido y Fecha de Nacimiento). Puedes utilizar los asistentes de NetBeans para crear una aplicación CRUD JSF. 

Pasos:


1. Crea una nueva base de datos. En el menú Window>Services de NetBeans podrás abrir el panel donde se visualizan las bases de datos (Databases). Haz clic con el botón derecho sobre la entrada "Java DB" dentro del apartado Databases y selecciona Create Database... Dale un nombre a la base de datos, como por ejemplo, Persona. Como nombre de usuario utiliza APP ya que es un esquema que se crea por defecto junto con la base, lo que te permitirá disponer rápidamente de acceso sin necesidad de ejecutar ninguna instrucción adicional. Añade una contraseña (en nuestro ejemplo, 123) Al pulsar el botón OK deberías ver que aparece enumerada la base de datos Persona bajo el apartado de Java DB. Además, aparecerá una entrada "jdbc:derby://localhost:1527/Persona [APP on APP]" bajo el nodo Databases.


 2. Una vez creada la base de datos, proseguimos con la creación de la tabla PERSONA. Para ello vete al mencionado nodo "jdbc:derby://localhost:1527/Persona [APP on APP]" y sigue la ruta APP>Tables. Obviamente, está vacío, a la espera de que creemos nuestra primera tabla. Haz clic con el botón derecho sobre "Tables". En el menú contextual que aparece podrás optar por crear la tabla indicando una a una la especificación de sus atributos (Create table...) Otra opción es seleccionar "Recreate table..." que te permite importar un script con las sentencias SQL necesarias para su creación. Puedes descargar el script para nuestra tabla: PERSONA.grab



3. El siguiente paso es crear una entidad de persistencia Persona pero antes necesitamos un nuevo proyecto web. Podrás hacerlos desde el menú File>New Project...>Java Web>Web application. En nuestro caso, le hemos llamado "EjercicioPersona". Para crear la entidad Persona vamos a File>New File...>Persistence>Entity Classes from Database) y seguimos los pasos del asistente.

a. Accediendo al asistente para crear entidades de persistencia a partir del esquema de base de datos.
b. En el apartado Data Source del segundo paso del asistente debemos crear un nombre JNDI para designar a nuestra conexión (opción New Data Source... que aparece al final de la lista desplegable de data sources)
c.  Seleccionamos nuestra única tabla PERSONAS
d. Escribimos un nombe de paquete donde incluir la clase entidad.

e. La entidad JPA ha sido generada con éxito y aparece en el paquete especificado con anterioridad.

4. Ya sólo queda crear toda la infraestructura de facelets para dar soporte a la interfaz gráfica y las clases que implementa el patrón DAO para manejar la entidad permitiendo todas las operaciones habituales sobre una tabla: guardar, eliminar, actualizar y buscar. Para ello, de nuevo, empleamos el asistente desde el menú File > New File...>Java Server Faces>JSF Pages from Entity Classes y seguimos todos los pasos.

a. Accedemos al asistente para crear páginas JSF a partir de la clase entidad.

b. Seleccionamos nuestra única tabla PERSONA

c. Aunque, por defecto, el asistente emplea el mismo paquete para todas las clases, conviene separar los Bean de Session en un subpaquete distinto, para mayor claridad en la estructuración del código.

d. Al finalizar el asistente, se crearán todos los nuevos componentes necesarios y ya dispondremos de una aplicación perfectamente funcional.


5. Por defecto, todas las etiquetas y mensajes aparecerán en inglés pero éstas se hayan definidas en un archivo de propiedades "Bundle.properties" que podremos traducir. Puntualmente, algunas de ellas pueden estar definidas directamente en los atributos de los tags dentro de los facelets. 


6. Asimismo, las fechas son tratadas con el patrón anglosajón en el que el mes precede al día. Conviene modificar todos los facelets donde aparezca dicho patrón.