¡Bienvenidos a todos! Esta publicación formará parte de una serie de 10 publicaciones que estaré desarrollando para aprender a crear una aplicación web en Java, bajo la plataforma JEE usando los frameworks de JPA y JSF. Este será un curso en forma de guía para todas aquellas personas que estén empezando en el mundo de la programación web.
En este curso aprenderemos a desarrollar aplicaciones web en N-CAPAS utilizando los patrones de diseño JEE, el estilo arquitectónico MVC y las funcionalidades provistas por los framework JSF (Java Server Faces) a nivel de vista-controlador y por JPA (Java Persistence API) a nivel de persistencia.
Este curso estará dividido en dos partes, En la primera parte, aprenderemos a configurar y utilizar el framework JPA mediante el desarrollo de aplicaciones Stand.Alone. En la segunda parte, aprenderemos a utilizar el framework JSF para desarrollar aplicaciones web. Por último, integraremos las funcionalidades de ambos frameworks en una aplicación final.
En este curso aprenderemos a desarrollar aplicaciones web en N-CAPAS utilizando los patrones de diseño JEE, el estilo arquitectónico MVC y las funcionalidades provistas por los framework JSF (Java Server Faces) a nivel de vista-controlador y por JPA (Java Persistence API) a nivel de persistencia.
Este curso estará dividido en dos partes, En la primera parte, aprenderemos a configurar y utilizar el framework JPA mediante el desarrollo de aplicaciones Stand.Alone. En la segunda parte, aprenderemos a utilizar el framework JSF para desarrollar aplicaciones web. Por último, integraremos las funcionalidades de ambos frameworks en una aplicación final.
APLICACIÓN
Se presenta un formulario donde se debe ingresar los datos para el registro de un trabajador y al presionar el botón “Procesar”, la aplicación responde con una página de registro completo mostrando los datos ingresados (ver imagen 1). Además implementaremos la interfaz PhaseListener para monitorear la ejecución de faces del JSF, aprenderemos a crear plantillas usando FACELETS, veremos una demostración de como podemos relacionar EJBs o simplemente Beans, veremos los diferentes tipos de ámbitos que existen y que podemos utilizar en nuestra aplicación; y emplearemos archivos de recursos de textos para el cambio de idioma i18n (internacionalización), conversiones, validaciones y eventos.
.
.
Imagen 1 |
(1) Pasos para la configuración del proyecto
Paso 1 - Crear un proyecto web en java
Acceda al siguiente link para saber como crear un "Dynamic Web Proyect" usando Eclipse como IDE.
Paso 2 - Agregar las librerías básicas de JSF
Si se está ejecutando la aplicación en un contenedor web que no soporta a JSF, las librerías del framework deben colocarse en el fólder “lib” de la aplicación (ver imagen 2):
Si se está ejecutando la aplicación en un contenedor web que no soporta a JSF, las librerías del framework deben colocarse en el fólder “lib” de la aplicación (ver imagen 2):
Clic aquí para descargar las librerías.
Paso 3 - Configurar el Faces Servlet
Dentro del archivo descriptor o deployment descriptor "web.xml" de la aplicación (ubicado en la carpeta WEB-INF del WebContent), se debe registrar el servlet controlador llamado “Faces Controller”.
Paso 3 - Configurar el Faces Servlet
Dentro del archivo descriptor o deployment descriptor "web.xml" de la aplicación (ubicado en la carpeta WEB-INF del WebContent), se debe registrar el servlet controlador llamado “Faces Controller”.
faces/inicio.xhtml Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet /faces/* javax.faces.DEFAULT_SUFFIX .xhtml javax.faces.FACELETS_SKIP_COMMENTS true javax.faces.VALIDATE_EMPTY_FIELDS false
Paso 4 - Configurar el JSFListener
💁 Opcionalmente se puede tener un archivo de configuración de JSF llamado faces.config.xml el cual está ubicado al mismo nivel que el web.xml dentro de la carpeta WEB-INF del WebContent.
El archivo contiene la configuración de todos los elementos de una aplicación JSF, aunque también pueden emplearse “anotaciones” en el código java para evitar el uso de éste archivo. Un ejemplo del contenido del archivo faces-config.xml se puede apreciar en el código más adelante.
💁 i18n o Internacionalización: Como uno de los objetivos de JSF. Permite especificar un modelo para el manejo de i18N en los componentes UI.
JSF proporciona el manejo de “resource bundles” así como de localización (L10N). Los componentes UI automáticamente reconocen estas características una vez que el “bundle” ha sido configurado.
El listener debe registrarse en el archivo "faces-config.xml" dentro de la carpeta WEB-INF del WebContent.
💁 Opcionalmente se puede tener un archivo de configuración de JSF llamado faces.config.xml el cual está ubicado al mismo nivel que el web.xml dentro de la carpeta WEB-INF del WebContent.
El archivo contiene la configuración de todos los elementos de una aplicación JSF, aunque también pueden emplearse “anotaciones” en el código java para evitar el uso de éste archivo. Un ejemplo del contenido del archivo faces-config.xml se puede apreciar en el código más adelante.
💁 i18n o Internacionalización: Como uno de los objetivos de JSF. Permite especificar un modelo para el manejo de i18N en los componentes UI.
JSF proporciona el manejo de “resource bundles” así como de localización (L10N). Los componentes UI automáticamente reconocen estas características una vez que el “bundle” ha sido configurado.
El listener debe registrarse en el archivo "faces-config.xml" dentro de la carpeta WEB-INF del WebContent.
pe.edu.aprender.listener.JSFListener pe.edu.aprender.recursos.textos textope.edu.aprender.recursos.textos es en
💁 i18n o Internacionalización: Como uno de
los objetivos de JSF. Permite especificar un modelo para el manejo de i18N
en los componentes UI.
JSF proporciona el manejo de “resource bundles” así como de localización (L10N). Los componentes UI automáticamente reconocen estas características una vez que el “bundle” ha sido configurado.
Es posible proporcionar un “Resource Bundle” (archivo .properties) con los mensajes que se desea manejar y de esa forma sobre escribir los mensajes por defecto de JSF. Para ello se debe agregar el siguiente bloque al archivo faces-config.xml como se muestra en el siguiente código:
En este ejemplo, los textos de los mensajes se tomarán desde un archivo .properties, como se puede apreciar en el siguiente código.
Tener en cuenta que este archivo requiere que los tags vayan en cierto orden(debido al DTD). En este ejemplo se está indicando que el archivo de mensajes se llama “textos.properties” y que los idiomas soportados son Español e Inglés. Además, se debe tener en cuenta que para sobre escribir los mensajes por defecto, el archivo de mensajes debe tener como “key” los messagesID del framework y como “value”, los textos que se desea para la aplicación.
(2) Crear clases
JSF proporciona el manejo de “resource bundles” así como de localización (L10N). Los componentes UI automáticamente reconocen estas características una vez que el “bundle” ha sido configurado.
Es posible proporcionar un “Resource Bundle” (archivo .properties) con los mensajes que se desea manejar y de esa forma sobre escribir los mensajes por defecto de JSF. Para ello se debe agregar el siguiente bloque al archivo faces-config.xml como se muestra en el siguiente código:
En este ejemplo, los textos de los mensajes se tomarán desde un archivo .properties, como se puede apreciar en el siguiente código.
Tener en cuenta que este archivo requiere que los tags vayan en cierto orden(debido al DTD). En este ejemplo se está indicando que el archivo de mensajes se llama “textos.properties” y que los idiomas soportados son Español e Inglés. Además, se debe tener en cuenta que para sobre escribir los mensajes por defecto, el archivo de mensajes debe tener como “key” los messagesID del framework y como “value”, los textos que se desea para la aplicación.
(2) Crear clases
Paso 1 - Crear el listener PhaseListener.java
💁 Los eventos de fase o “Phase Events” se procesan entre cada fase del procesamiento del ciclo de vida de un request. Se puede crear un Listener simplemente implementando la interfaz PhaseListener.
Esta interfaz posee tres métodos que deben ser implementados:
· beforePhase()
· afterPhase()
· getPhaseId()
➢ Los métodos beforePhase() y afterPhase() se ejecutan para todas las fases del ciclo de procesamiento de un request, por tanto, si se desea ejecutar alguna lógica especial en determinada fase, se deberá obtener el ID de la fase y en base a condiciones, controlar el flujo del código.
➢ Los métodos beforePhase() y afterPhase() se ejecutan para todas las fases del ciclo de procesamiento de un request, por tanto, si se desea ejecutar alguna lógica especial en determinada fase, se deberá obtener el ID de la fase y en base a condiciones, controlar el flujo del código.
➢ El método getPhaseId() sirve para determinar a que fase está asociado el listener. Cuando se usa para cualquier fase retorna el valor ANY_PHASE.
. JSFListener.java
Paso 2 - Crear los beans relacionados: Cargo.java, Casillero.java y Empleado.java
Paso 2 - Crear los beans relacionados: Cargo.java, Casillero.java y Empleado.java
. Cargo.java
. Casillero.java
package pe.edu.aprender.entity; import java.io.Serializable; public class Casillero implements Serializable { private static final long serialVersionUID = 1L; private int codigo; private String descripcion; private Empleado empleado; // Relacio de 1 a 1 public Empleado getEmpleado() { return empleado; } public void setEmpleado(Empleado empleado) { this.empleado = empleado; } public int getCodigo() { return codigo; } public void setCodigo(int codigo) { this.codigo = codigo; } public String getDescripcion() { return descripcion; } public void setDescripcion(String descripcion) { this.descripcion = descripcion; } @Override public String toString() { return "Casillero [codigo=" + codigo + ", descripcion=" + descripcion + ", empleado=" + empleado + "]"; } }
. Empleado.java
package pe.edu.aprender.entity; import java.util.Date; public class Empleado { private Integer id; private String apellido; private String nombre; private Integer edad; private String area; private Date fechaIngreso; private Boolean estado; private Cargo cargo; // Relación de M a 1 private Casillero casillero; // Relación de 1 a 1 public Empleado() { cargo = new Cargo(); casillero = new Casillero(); } public Empleado(Integer id, String apellido, String nombre) { this.id = id; this.apellido = apellido; this.nombre = nombre; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getApellido() { return apellido; } public void setApellido(String apellido) { this.apellido = apellido; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public Integer getEdad() { return edad; } public void setEdad(Integer edad) { this.edad = edad; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } public Date getFechaIngreso() { return fechaIngreso; } public void setFechaIngreso(Date fechaIngreso) { this.fechaIngreso = fechaIngreso; } public Boolean getEstado() { return estado; } public void setEstado(Boolean estado) { this.estado = estado; } public Cargo getCargo() { return cargo; } public void setCargo(Cargo cargo) { this.cargo = cargo; } public Casillero getCasillero() { return casillero; } public void setCasillero(Casillero casillero) { this.casillero = casillero; } }
Paso 3 - Crear los managedBean FormularioBean.java, SessionBean.java y LocaleBean.java
💁 Un "Manged Bean" es una clase java que representa información de un formulario web y existe dos maneras de configurarlos:
➢ Usando anotaciones dentro del programa Java. Es la forma más recomendada pues permite un código más cohesionado y fácil de mantener. Se emplea la anotación @ManagedBean antes de la definición de la clase (desde JSF 2.0).
➢ Usando XML dentro del archivo faces-config.xml. Se emplea el tag <managed-bean> para efectuar la declaración
💁 Un “managed Bean” típicamente tiene 3 partes:
a) Las propiedades del Bean: generalmente un getter y un setter por cada atributo. Los métodos setter son invocados automáticamente por el JSF cuando el formulario web es enviado.
b) Métodos para controlar acciones: Generalmente es sólo un método, pero podrían ser varios si es que el formulario posee múltiples botones de envío.
c) Un lugar para los datos resultantes: No es invocado automáticamente por JSF. Debe ser llenado por el método controlador en base a los resultados de la lógica de negocio.
💁 Un "Manged Bean" es una clase java que representa información de un formulario web y existe dos maneras de configurarlos:
➢ Usando anotaciones dentro del programa Java. Es la forma más recomendada pues permite un código más cohesionado y fácil de mantener. Se emplea la anotación @ManagedBean antes de la definición de la clase (desde JSF 2.0).
➢ Usando XML dentro del archivo faces-config.xml. Se emplea el tag <managed-bean> para efectuar la declaración
💁 Un “managed Bean” típicamente tiene 3 partes:
a) Las propiedades del Bean: generalmente un getter y un setter por cada atributo. Los métodos setter son invocados automáticamente por el JSF cuando el formulario web es enviado.
b) Métodos para controlar acciones: Generalmente es sólo un método, pero podrían ser varios si es que el formulario posee múltiples botones de envío.
c) Un lugar para los datos resultantes: No es invocado automáticamente por JSF. Debe ser llenado por el método controlador en base a los resultados de la lógica de negocio.
. FormularioBean.java
. SessionBean.java
💁 Los tipos de ámbitos para marcar los managed Beans pueden ser:
➢ none - @NoneScoped (sólo JSF 2.0)
Los Managed Beans con éste ámbito no se generan ni almacenan en ningún ámbito. Ellos son generados bajo demanda por otros Managed Beans. Su tiempo de vida depende del Managed Bean que lo invocó.
Puede referenciar a otros managed Beans del ámbito: none.
➢ request - @RequestScoped
Pueden ser generados y están disponibles durante una petición HTTP simple. Esto significa que el Bean sobrevive a la navegación hacia otra pagina.
Puede referenciar a otros managed Beans del ámbito: none, request, view, session, application.
➢ view - @ViewScoped (sólo JSF 2.0)
Permanecen disponibles durante el tiempo que el usuario permanezca en la misma vista. Al salir de dicha vista, los Managed Beans son eliminados.
Puede referenciar a otros managed Beans del ámbito: none, view, session, application.
➢ session - @SessionScoped
Se almacenan en la sesión HTTP. Esto significa que los valores de sus atributos son almacenados a lo largo de múltiples peticiones HTTP para un usuario.
Puede referenciar a otros managed Beans del ámbito: none, session, application.
➢ application - @ApplicationScoped
Retienen sus valores a lo largo de la vida de una aplicación, por lo que están disponibles para TODOS los usuarios.
Puede referenciar a otros managed Beans del ámbito: none, application.
➢ Custom - @CustomScoped(value="#{someMap}")
El bean se almacena en un Mapa y el desarrollador tiene el control del ciclo de vida del mismo.
Como se ve en el ejemplo, el “Managed Bean” está marcado para funcionar en el ámbito @SessionScoped. Se almacenan en la sesión HTTP. Esto significa que los valores de sus atributos son almacenados a lo largo de múltiples peticiones HTTP para un usuario.
💁 Los tipos de ámbitos para marcar los managed Beans pueden ser:
➢ none - @NoneScoped (sólo JSF 2.0)
Los Managed Beans con éste ámbito no se generan ni almacenan en ningún ámbito. Ellos son generados bajo demanda por otros Managed Beans. Su tiempo de vida depende del Managed Bean que lo invocó.
Puede referenciar a otros managed Beans del ámbito: none.
➢ request - @RequestScoped
Pueden ser generados y están disponibles durante una petición HTTP simple. Esto significa que el Bean sobrevive a la navegación hacia otra pagina.
Puede referenciar a otros managed Beans del ámbito: none, request, view, session, application.
➢ view - @ViewScoped (sólo JSF 2.0)
Permanecen disponibles durante el tiempo que el usuario permanezca en la misma vista. Al salir de dicha vista, los Managed Beans son eliminados.
Puede referenciar a otros managed Beans del ámbito: none, view, session, application.
➢ session - @SessionScoped
Se almacenan en la sesión HTTP. Esto significa que los valores de sus atributos son almacenados a lo largo de múltiples peticiones HTTP para un usuario.
Puede referenciar a otros managed Beans del ámbito: none, session, application.
➢ application - @ApplicationScoped
Retienen sus valores a lo largo de la vida de una aplicación, por lo que están disponibles para TODOS los usuarios.
Puede referenciar a otros managed Beans del ámbito: none, application.
➢ Custom - @CustomScoped(value="#{someMap}")
El bean se almacena en un Mapa y el desarrollador tiene el control del ciclo de vida del mismo.
Como se ve en el ejemplo, el “Managed Bean” está marcado para funcionar en el ámbito @SessionScoped. Se almacenan en la sesión HTTP. Esto significa que los valores de sus atributos son almacenados a lo largo de múltiples peticiones HTTP para un usuario.
. LocaleBean.java
package pe.edu.aprender.managed; import java.util.Locale; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; @ManagedBean(name = "idioma") @SessionScoped public class LocaleBean { private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale(); private String idioma; public Locale getLocale() { return locale; } public String getIdioma() { return idioma; } public void setIdioma(String idioma) { locale = new Locale(idioma); } }
(3) Crear los archivos de recursos de texto
Paso 1 - Crear los archivo textos.properties y textos_en.properties dentro del paquete pe.edu.aprender.recursos
. textos.properties
cabecera_titulo=Desarrollo de Aplicaciones Web II menu_item1=Iniciar contenido_titulo=Bienvenido pie_titulo=MI SITIO WEB registro_titulo=Registro resultado_titulo=Resultado listado_titulo=Listado campo_nombre=Nombre campo_apellido=Apellido campo_area=Area campo_edad=Edad campo_fecha_ingreso=Fecha Ingreso campo_casillero=Casillero campo_cargo=Cargo campo_habilitado=¿Habilitado? campo_codigo=Codigo campo_nombre_completo=Nombre Completo boton_procesar=Procesar boton_continuar=Continuar boton_listado=Listado mensaje_registro_exitoso=Registro completo # Algunos de los messageID estándares que pueden ser sobre escritos son: javax.faces.component.UIInput.REQUIRED={0}: Dato Obligatorio javax.faces.validator.RegexValidator.NOT_MATCHED=No cumple formato javax.faces.validator.RegexValidator.NOT_MATCHED_detail=Valor de campo ''{1}'' no cumple formato javax.faces.validator.LengthValidator.MAXIMUM={1}: Longitud de texto mayor a la permitida: ''{0}'' javax.faces.validator.LengthValidator.MINIMUM={1}: Longitud de texto menor a la permitida: ''{0}'' javax.faces.validator.LongRangeValidator.NOT_IN_RANGE={2}: Valor fuera de rango ( {0} - {1} )
. textos_en.properties
cabecera_titulo=Web Applications II menu_item1=Start contenido_titulo=Welcome pie_titulo=MY WEB SITE registro_titulo=New resultado_titulo=Result listado_titulo=List campo_nombre=First Name campo_apellido=Last Name campo_area=Area campo_edad=Age campo_fecha_ingreso=Join Date campo_casillero=Locker campo_cargo=Employment campo_habilitado=Enabled? campo_codigo=Code campo_nombre_completo=Full Name boton_procesar=Process boton_continuar=Continue boton_listado=List mensaje_registro_exitoso=successful registration #Algunos de los messageID estándares que pueden ser sobre escritos son: javax.faces.component.UIInput.REQUIRED={0}: Required javax.faces.validator.RegexValidator.NOT_MATCHED= Incorrect Format javax.faces.validator.RegexValidator.NOT_MATCHED_detail=Value of ''{1}'' has incorrect format javax.faces.validator.LengthValidator.MAXIMUM={1}: Maximum length: ''{0}'' javax.faces.validator.LengthValidator.MINIMUM={1}: Minimum length: ''{0}'' javax.faces.validator.LongRangeValidator.NOT_IN_RANGE={2}: Value out of range ( {0} - {1} )
Algunos
de los messageID estándares que pueden ser sobre escritos son:
· javax.faces.component.UIInput.CONVERSION
· javax.faces.component.UIInput.REQUIRED
· javax.faces.component.UISelectOne.INVALID
· javax.faces.component.UISelectMany.INVALID
· javax.faces.converter.BigDecimalConverter.DECIMAL
· javax.faces.converter.BigIntegerConverter.BIGINTEGER
· javax.faces.converter.BooleanConverter.BOOLEAN
· javax.faces.converter.ByteConverter.BYTE
· javax.faces.converter.CharacterConverter.CHARACTER
· javax.faces.converter.DateTimeConverter.DATE
· javax.faces.converter.DateTimeConverter.TIME
· javax.faces.converter.DateTimeConverter.DATETIME
· javax.faces.converter.DateTimeConverter.PATTERN_TYPE
· javax.faces.converter.DoubleConverter.DOUBLE
· javax.faces.converter.FloatConverter.FLOAT
· javax.faces.converter.IntegerConverter.INTEGER
· javax.faces.converter.LongConverter.LONG
· javax.faces.converter.NumberConverter.CURRENCY
· javax.faces.converter.NumberConverter.PERCENT
· javax.faces.converter.NumberConverter.NUMBER
· javax.faces.converter.NumberConverter.PATTERN
· javax.faces.converter.ShortConverter.SHORT
· javax.faces.converter.STRING
· javax.faces.validator.NOT_IN_RANGE
· javax.faces.validator.DoubleRangeValidator.MAXIMUM
· javax.faces.validator.DoubleRangeValidator.MINIMUM
· javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE
· javax.faces.validator.DoubleRangeValidator.TYPE
· javax.faces.validator.LengthValidator.MAXIMUM
· javax.faces.validator.LengthValidator.MINIMUM
· javax.faces.validator.LongRangeValidator.MAXIMUM
· javax.faces.validator.LongRangeValidator.MINIMUM
· javax.faces.validator.LongRangeValidator.NOT_IN_RANGE
· javax.faces.validator.LongRangeValidator.TYPE
(4) Crear la plantilla faceles
· javax.faces.component.UIInput.CONVERSION
· javax.faces.component.UIInput.REQUIRED
· javax.faces.component.UISelectOne.INVALID
· javax.faces.component.UISelectMany.INVALID
· javax.faces.converter.BigDecimalConverter.DECIMAL
· javax.faces.converter.BigIntegerConverter.BIGINTEGER
· javax.faces.converter.BooleanConverter.BOOLEAN
· javax.faces.converter.ByteConverter.BYTE
· javax.faces.converter.CharacterConverter.CHARACTER
· javax.faces.converter.DateTimeConverter.DATE
· javax.faces.converter.DateTimeConverter.TIME
· javax.faces.converter.DateTimeConverter.DATETIME
· javax.faces.converter.DateTimeConverter.PATTERN_TYPE
· javax.faces.converter.DoubleConverter.DOUBLE
· javax.faces.converter.FloatConverter.FLOAT
· javax.faces.converter.IntegerConverter.INTEGER
· javax.faces.converter.LongConverter.LONG
· javax.faces.converter.NumberConverter.CURRENCY
· javax.faces.converter.NumberConverter.PERCENT
· javax.faces.converter.NumberConverter.NUMBER
· javax.faces.converter.NumberConverter.PATTERN
· javax.faces.converter.ShortConverter.SHORT
· javax.faces.converter.STRING
· javax.faces.validator.NOT_IN_RANGE
· javax.faces.validator.DoubleRangeValidator.MAXIMUM
· javax.faces.validator.DoubleRangeValidator.MINIMUM
· javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE
· javax.faces.validator.DoubleRangeValidator.TYPE
· javax.faces.validator.LengthValidator.MAXIMUM
· javax.faces.validator.LengthValidator.MINIMUM
· javax.faces.validator.LongRangeValidator.MAXIMUM
· javax.faces.validator.LongRangeValidator.MINIMUM
· javax.faces.validator.LongRangeValidator.NOT_IN_RANGE
· javax.faces.validator.LongRangeValidator.TYPE
(4) Crear la plantilla faceles
💁 Desarrollada como una extensión de JSF con el objetivo de reemplazar el uso de JSP, permiten a los desarrolladores declarar componentes UI en diferentes tecnologías de presentación utilizando para ello plantillas (templates) HTML de manera tal que permita la composición de una vista a partir de diferentes páginas físicas separadas.
Las páginas en Facelets se generan usando XHTML. La idea de usar XHTML es hacer portables a las páginas entre diversos ambientes de desarrollo. Además, Facelets requiere el uso de “XML namespaces” para soportar las siguientes librerías de tags:
· JSF HTML Tag Library.
· JSF Core Tag Library.
· JSTL Core Tag Library.
· JSTL Functions Tag Library.
· JSF Facelets Tag Library.
💁 La construcción de páginas se realiza con “Facelets XHTML” empleando para ello “tag libraries”.
➢ Se puede declarar las librerías usando “XML namespaces”:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
➢ o usando la forma tradicional:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
Paso 1 - Crear un template y sus paginas clientes
Crear el template ("plantilla.xhtml") y las viewID o paginas clientes ("cabecera.xhtml", "menu.xhtml" y "pie.xhtml") dentro del WebContent de la aplicación (ver imagen 3).
. plantilla.xhml
💁 Una gran característica de los Facelets (no disponible en JSP) es el poder generar “templates”. Un “template” es una página XHTML que emplea algunos tags de Facelets para definir varias “divisiones” lógicas de la vista como por ejemplo: cabecera, pie de página y contenido. La idea es tener partes reusables de código sin tener que repetir el mismo código en diferentes páginas.
a) Observe las primeras líneas de código en el tag <html>. Se declaran los “namespaces” de las librerías.
b) Observe la línea 13 para ver el uso de “resources folders”. En este caso, la aplicación busca un folder “resources” y dentro de este, busca el nombre de la library que está como parámetro (“css”).
c) Observe los bloques con el tag <ui:insert>. Lo que está dentro del bloque es el valor por defecto de esa zona (si es que el viewID no reemplazara nada).
d) Los tags <ui:include> permiten incoporar contenido que se encuentra en otros archivos, dentro del template o de la viewId.
Las páginas en Facelets se generan usando XHTML. La idea de usar XHTML es hacer portables a las páginas entre diversos ambientes de desarrollo. Además, Facelets requiere el uso de “XML namespaces” para soportar las siguientes librerías de tags:
· JSF HTML Tag Library.
· JSF Core Tag Library.
· JSTL Core Tag Library.
· JSTL Functions Tag Library.
· JSF Facelets Tag Library.
💁 La construcción de páginas se realiza con “Facelets XHTML” empleando para ello “tag libraries”.
➢ Se puede declarar las librerías usando “XML namespaces”:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
➢ o usando la forma tradicional:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
Paso 1 - Crear un template y sus paginas clientes
Crear el template ("plantilla.xhtml") y las viewID o paginas clientes ("cabecera.xhtml", "menu.xhtml" y "pie.xhtml") dentro del WebContent de la aplicación (ver imagen 3).
Imagen 3 |
💁 Una gran característica de los Facelets (no disponible en JSP) es el poder generar “templates”. Un “template” es una página XHTML que emplea algunos tags de Facelets para definir varias “divisiones” lógicas de la vista como por ejemplo: cabecera, pie de página y contenido. La idea es tener partes reusables de código sin tener que repetir el mismo código en diferentes páginas.
a) Observe las primeras líneas de código en el tag <html>. Se declaran los “namespaces” de las librerías.
b) Observe la línea 13 para ver el uso de “resources folders”. En este caso, la aplicación busca un folder “resources” y dentro de este, busca el nombre de la library que está como parámetro (“css”).
c) Observe los bloques con el tag <ui:insert>. Lo que está dentro del bloque es el valor por defecto de esa zona (si es que el viewID no reemplazara nada).
d) Los tags <ui:include> permiten incoporar contenido que se encuentra en otros archivos, dentro del template o de la viewId.
. cabecera.xhtml
. menu.xhtml
. pie.xhtml
(4) Crear las páginas XHTML
Paso 1 - Crear la página inicio.xhtml, formulario.xhtml, resultado.xhtml y final.xhtml dentro del webContent.
a) Observe las declaraciones del tag <ui:composition> en la primeras líneas.
b) En la línea 9 se indica cual es el archivo de “layout” con el que trabaja ésta página.
c) Los bloques <ui:define> sirven para reemplazar el contenido de cada bloque dentro de la zona de la plantilla identificada con el mismo nombre.
d) Tenga en cuenta que el contenido que se encuentre fuera de los tags <ui:composition> no aparecerá en los clientes.
Paso 1 - Crear la página inicio.xhtml, formulario.xhtml, resultado.xhtml y final.xhtml dentro del webContent.
a) Observe las declaraciones del tag <ui:composition> en la primeras líneas.
b) En la línea 9 se indica cual es el archivo de “layout” con el que trabaja ésta página.
c) Los bloques <ui:define> sirven para reemplazar el contenido de cada bloque dentro de la zona de la plantilla identificada con el mismo nombre.
d) Tenga en cuenta que el contenido que se encuentre fuera de los tags <ui:composition> no aparecerá en los clientes.
. inicio.xhtml
. formulario.xhtml
Conversiones, Validaciones y Eventos
JSF proporciona componentes para manejar los aspectos de conversión y validación en el desarrollo de aplicaciones:
Adicionalmente, como ya hemos visto, JSF proporciona un sistema de mensajes. Esto permite a los desarrolladores controlar la visualización de los mensajes de conversión y validación en las páginas, de una manera flexible utilizando uno o más tags de tipo <h:message> o <h:messages>.
Convertidores
Todos los “converters” se puede llamar usando el tag <f:converter> y especificando el ID, a excepción de DateTimeConverter y NumberConverter que tienen sus propios tags.
La forma implícita de conversión se realiza cuando JSF conoce el tipo de dato del valor. Por ejemplo, asumiendo que “age” es un atributo de tipo Integer del managed bean “user”, en el siguiente caso la conversión es implícita:
<h:inputText id="age" value="#{user.age}"/>.
La forma explícita es cuando se usan los tres tags que proporciona la librería core de JSF:
<f:convertDateTime>, <f:convertNumber> y <f:converter>.
Para vincular un Componente UI con un converter, simplemente hay que anidar el converter dentro del tag:
<h:inputText value="#{formulario.empleado.fechaIngreso}" id="txtFecha">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
Validadores
Los validadores se pueden asociar a los componentes UI de dos maneras: usando tags de la librería core o utilizando el MethodBinding.
Usando los tags de la librería core:
<f:validateDoubleRange>, <f:validateLongRange>, <f:validateLength> y <f:validateRegex>.
Usando el MethodBinding. En este caso, se asocia a un método del managed bean “user”:
<h:inputText validator="#{user.validateAge}" value="#{user.age}"/>
public void validateAge(FacesContext context, UIComponent component, Object Value) {
// Validation code here
}
Opcional (para pruebas) para que JSF no valide campos que están vacíos se debe agregar lo siguiente al web.xml:
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
. resultado.xhtml
JSF proporciona componentes para manejar los aspectos de conversión y validación en el desarrollo de aplicaciones:
Adicionalmente, como ya hemos visto, JSF proporciona un sistema de mensajes. Esto permite a los desarrolladores controlar la visualización de los mensajes de conversión y validación en las páginas, de una manera flexible utilizando uno o más tags de tipo <h:message> o <h:messages>.
Convertidores
Todos los “converters” se puede llamar usando el tag <f:converter> y especificando el ID, a excepción de DateTimeConverter y NumberConverter que tienen sus propios tags.
La forma implícita de conversión se realiza cuando JSF conoce el tipo de dato del valor. Por ejemplo, asumiendo que “age” es un atributo de tipo Integer del managed bean “user”, en el siguiente caso la conversión es implícita:
<h:inputText id="age" value="#{user.age}"/>.
La forma explícita es cuando se usan los tres tags que proporciona la librería core de JSF:
<f:convertDateTime>, <f:convertNumber> y <f:converter>.
Para vincular un Componente UI con un converter, simplemente hay que anidar el converter dentro del tag:
<h:inputText value="#{formulario.empleado.fechaIngreso}" id="txtFecha">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
Validadores
Los validadores se pueden asociar a los componentes UI de dos maneras: usando tags de la librería core o utilizando el MethodBinding.
Usando los tags de la librería core:
<f:validateDoubleRange>, <f:validateLongRange>, <f:validateLength> y <f:validateRegex>.
Usando el MethodBinding. En este caso, se asocia a un método del managed bean “user”:
<h:inputText validator="#{user.validateAge}" value="#{user.age}"/>
public void validateAge(FacesContext context, UIComponent component, Object Value) {
// Validation code here
}
Opcional (para pruebas) para que JSF no valide campos que están vacíos se debe agregar lo siguiente al web.xml:
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
. resultado.xhtml
. listado.xhtml
. final.xhtml
Paso 2 - Ejecutar la aplicación
Hay dos formas de poder ejecutar nuestra aplicación para poder probarla. Esto es valido solo si estas usando Apache Tomcat.
1. La primera y la más sencilla es el despliegue automático, es decir, que Eclipse se encargue de ello, tan solo dando clic derecho al proyecto y seleccionar la opción "Run As/Run on Server". Eclipse iniciará el servidor por nosotros y abrirá el navegador con la siguiente URL "localhost:8080/Aplicacion_18_final_JSF_06/faces/inicio.xhtml". Si te preguntas, como es que Eclipse hace este trabajo, es muy sencillo. Lo que hace Eclipse, es publicar el proyecto en un directorio dentro del workspace, en mi caso en la siguiente ruta "G:\Programación\Programas\VersionesEclipse\workspace\indigo\SesionesDAW2\metadata\plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps". Esto se puede ver dando clic derecho al proyecto y seleccionar la opción "Run As/Run Configurations" como se muestra en la siguiente imagen, donde se puede ver como Eclipse inicia Tomcat con la aplicación (ver imagen 4).
2. La segunda es el despliegue mediante un archivo .war (de Web Application Archive - Archivo de Aplicación Web), para luego copiarlo en la carpeta webapps del servidor tomcat y mediante linea de comandos poder deployarlo.
Hay dos formas de poder ejecutar nuestra aplicación para poder probarla. Esto es valido solo si estas usando Apache Tomcat.
1. La primera y la más sencilla es el despliegue automático, es decir, que Eclipse se encargue de ello, tan solo dando clic derecho al proyecto y seleccionar la opción "Run As/Run on Server". Eclipse iniciará el servidor por nosotros y abrirá el navegador con la siguiente URL "localhost:8080/Aplicacion_18_final_JSF_06/faces/inicio.xhtml". Si te preguntas, como es que Eclipse hace este trabajo, es muy sencillo. Lo que hace Eclipse, es publicar el proyecto en un directorio dentro del workspace, en mi caso en la siguiente ruta "G:\Programación\Programas\VersionesEclipse\workspace\indigo\SesionesDAW2\metadata\plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps". Esto se puede ver dando clic derecho al proyecto y seleccionar la opción "Run As/Run Configurations" como se muestra en la siguiente imagen, donde se puede ver como Eclipse inicia Tomcat con la aplicación (ver imagen 4).
Imagen 4 |
2. La segunda es el despliegue mediante un archivo .war (de Web Application Archive - Archivo de Aplicación Web), para luego copiarlo en la carpeta webapps del servidor tomcat y mediante linea de comandos poder deployarlo.
- Primero debemos exportar el proyecto. Para ello, hacemos clic derecho al proyecto y seleccionamos la opción "export/WAR File" (ver imagen 5).
- Copiamos el archivo .war a la carpeta webapps del servidor tomcat. En mi caso la ruta sería "C:\Apache\Apache Tomcat 7.0.22\webapps".
- Abrimos la consola de comandos CMD y accedemos al directorio en donde tenemos instalado el Tomcat. En mi caso lo tengo instalado en "C:\Apache\Apache Tomcat 7.0.22\bin". Para iniciar el servidor debemos digitar el comando "startup" y para apagar el servidor debemos digitar el comando "shutdown" (ver imagen 6).
- Abrimos el navegador y accedemos a URL del proyecto. En mi caso sería "localhost:8080/Aplicacion_18_final_JSF_06/faces/inicio.xhtml".
Imagen 5 |
Imagen 6 |
No hay comentarios, ¡cuéntame algo!
Me gustaría saber tu opinión. ¡Saludos!