Manual Jsf 2

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 48

DownloadManual Jsf 2
Open PDF In BrowserView PDF
Jsf – Enrique Pedraza
Table of Contents
Introducción..........................................................................................................................................2
Primera aplicación de ejemplo.............................................................................................................5
Código de la aplicación......................................................................................................................6
Eventos y oyentes JSF........................................................................................................................10
Implementación de oyentes como métodos de beans.......................................................................11
Eventos Action y navegabilidad.......................................................................................................12
Reglas de Navegación......................................................................................................................13
Componentes y etiquetas JSF.............................................................................................................16
Etiquetas html...................................................................................................................................17
Ejemplos de Uso de Etiquetas Html...................................................................................................26
Código de la aplicación....................................................................................................................28
Ciclo de vida de una petición JSF......................................................................................................33
El atributo immediate.......................................................................................................................36
Ejemplos reales de uso de immediate=”true”.....................................................................................37
Pushback de eventos valueChange...................................................................................................38
Objetos implícitos en una página jsf..................................................................................................39
Validación...........................................................................................................................................40
Conversores........................................................................................................................................41
Ajax y jsf............................................................................................................................................41
Comunicación en Jsf 2........................................................................................................................42
Oyentes de fases.................................................................................................................................42
I18N....................................................................................................................................................42
Misc....................................................................................................................................................44
Managed Beans..................................................................................................................................45
Aplicación de Gestión........................................................................................................................45

Introducción
JSF (Java Server Faces) es un framework de desarrollo basado en el patrón MVC (Modelo Vista
Controlador) orientado al interfaz de usuario. El modelo web estándar de desarrollo con servlets y
jsp se basa en peticiones a url determinadas que son procesadas por servlets que a su vez delegan la
construcción de la vista en páginas jsp, de esta forma:

El procesamiento típico cuando la petición llega al servlet es de recuperación de los parámetros que
envía el cliente, análisis de dichos parámetros, delegación en métodos de la capa de negocio en
función de esos parámetros y reenvío de los resultados a la página jsp para que construya la vista.
Este mecanismo termina resultando tedioso, repetitivo y propenso a errores. Hoy en día existen
frameworks de desarrollo, como Struts, Spring o JSF que automatizan y facilitan el desarrollo de
aplicaciones MVC para entornos web.
Lo que diferencia a JSF de otros frameworks similares es que JSF aspira a recuperar el modelo
tradicional de oyentes y eventos utilizado en aplicaciones monopuesto pero orientado a aplicaciones
web. Para ello cuenta con dos elementos principales:
•

Un api para representar los componentes de interfaz de usuario y manejar su estado;
gestionar eventos, validar en el servidor y convertir los datos; definir la navegación; soportar
internacionalización y accesibilidad; y proveer extensibilidad para todas estas
características.

•

Un conjunto de librerías personalizadas de etiquetas para páginas JSP que renderizan los
componentes de usuario en la página y que enlazan dichos componentes a objetos del lado
del servidor.

JSF es una especificación de Sun, liderada por Craig R. McClanahan, quien a su vez es el creador
de Struts. Es por ello que muchas características de Struts se encuentran también en la
especificación de JSF. Al ser una especificación, existen distintas implementaciones proporcionadas
por distintos fabricantes.
Modelo de ejecución:

JSF constituye una vuelta al paradigma evento/oyente característico de las aplicaciones
monopuesto. En una aplicación web clásica la interfaz de usuario se construye a través de etiquetas
HTML de esta forma:
Al enviar el formulario, el valor de los campos es recogido por un servlet uno a uno, con código parecido a éste: String nombre = request.getParameter(“nombreUsuario”); Esto puede convertirse en una tarea muy tediosa y muy propensa a errores cuando trabajamos con formularios muy grandes. Si a esto añadimos las tareas de conversión de los parámetros desde el tipo original en que son enviados (String), su validación, la presentación de errores, el rellenado de los formularios en caso de que exista un error en la página... nos encontramos con un sistema en el que malgastamos mucho tiempo en tareas repetitivas para las que ya existen diversas soluciones. Entre estas soluciones se encuentra JSF, que se diferencia de las demás en el enfoque evento/oyente hacia el que está orientado. Cuando trabajamos con JSF no pensamos en los parámetros que envía el cliente, sino en eventos que se pueden producir en nuestra página y en cómo reaccionar a dichos eventos. Una aplicación JSF se compone de: • Una capa de presentación normalmente compuesta por un conjunto de Facelets (páginas xhtml) junto con un conjunto de etiquetas personalizadas para representar los componentes en la página. • Componentes (objetos) del lado servidor que representan los componentes gráficos de la página • Renderers que dibujan estos componentes generando una salida adecuada a la presentación elegida. • Conversores y validadores que convierten y validan respectivamente los datos que envía el cliente. • Un conjunto de beans de soporte (Managed Beans) que definen propiedades para almacenar estos datos y métodos para reaccionar a los eventos de una página. • Un fichero de configuración donde podemos definir las reglas de navegación y configurar los beans y otros componentes. • Uno o varios ficheros de recursos con los mensajes de la aplicación en distintos idiomas. JSF proporciona elementos que facilitan el desarrollo de las capas de control y presentación y su integración con el modelo. Para este manual hemos utilizado la versión 2.1.9 de la especificación JSF (Mojarra) y Tomcat 8. Primera aplicación de ejemplo Para implementar una aplicación JSF básica necesitamos configurar o aportar los siguientes elementos: 1. Configurar el fichero web.xml para especificar qué peticiones va a procesar el entorno de JSF. 2. Crear páginas facelet (.xhtml) para mostrar al cliente. Estas páginas contendrán componentes de usuario, algunos de los cuales lanzarán eventos al ser manipulados. 3. Crear una o varias clases (Managed Beans) que almacenen la información suministrada por el cliente en las página facelets y que respondan (oyentes) a los posibles eventos que se produzcan en dichas páginas. 4. Opcionalmente, crear uno o varios ficheros de configuración (faces-config.xml, …) en la que podemos configurar diferentes elementos de la aplicación, como los Managed Beans, reglas de navegación, etc. Vamos a crear una aplicación básica para mostrar el funcionamiento de JSF. La aplicación va a consistir en una única página facelet con un campo de texto y un botón: Cuando escribamos algo en el campo de texto y pulsemos el botón, aparecerá un mensaje con el texto en mayúsculas: Para mostrar más características del framework obligaremos a que haya algo introducido en el campo de texto antes de pulsar el botón, y en caso contrario mostraremos un mensaje de validación estándar; además, el texto que acompaña al texto en mayúsculas permanecerá oculto hasta que escribamos algo y pulsemos el botón. Para compilar y desplegar vamos a necesitar las librerías JSF, en este caso estamos utilizando los ficheros jsf-api-2.1.9.jar y jsf-impl-2.1.9.jar. Código de la aplicación Fichero web.xml: En el fichero web.xml configuramos el servlet de JSF para que tramite las peticiones del cliente a la aplicación, además de configurar algunos parámetros del framework: jsf simple jsf simple javax.faces.STATE_SAVING_METHOD server javax.faces.PROJECT_STAGE Development Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.xhtml Como podemos observar primero declaramos un par de parámetros de contexto relativos al framework JSF, para a continuación declarar el servlet controlador JSF, asociarlo a peticiones con extensión .xhtml y establecer como página de inicio index.xhtml. Obviamos en este momento el listado de index.xhtml y mostramos el código de la página facelet pasaamayuscula.xhtml pasaamayuscula.xhtml Jsf Básico

Aplicación que pasa a Mayúscula

Cuando escribas algo en el campo de texto y pulses el botón aparecerá un mensaje mostrando el contenido del campo de texto en mayúsculas

El texto en mayúsculas es #{mayusBean.textoEnMayusculas}.
La página facelet es un fichero xhtml en el que construimos el interfaz de usuario a través de etiquetas JSF. Analicemos los elementos más significativos de la página: • : abrimos el formulario que contendrá componentes a procesar en el servidor. Daos cuenta de que no especificamos atributos method ni action. • : especificamos un : esta etiqueta dibuja un botón con el texto Pasar a mayúscula que cuando se pulsa invoca el método pasaAMayusculas del bean mayusBean. Este método está definido como un actionListener dentro de la aplicación. • : con esta etiqueta mostramos al usuario posibles errores de validación. • : la etiqueta panelGroup se usa para agrupar componentes en una página. En este caso la usamos combinada con el atributo rendered, que dibuja o no los componentes anidados en el panelGroup en función de la propiedad rendering de mayusBean. • #{mayusBean.textoEnMayusculas}: a partir de la versión 2.0 de JSF podemos utilizar EL para imprimir los atributos de un bean directamente sin necesidad de utilizar la etiqueta outputLabel. En este caso estamos mostrando el valor del atributo textoEnMayusculas del bean mayusBean. MayusBean.java @ManagedBean(name="mayusBean") @RequestScoped public class MayusBean { // En este caso el atributo name es redundante private String textoOriginal; private String textoEnMayusculas; private boolean rendering; public String getTextoOriginal() { return textoOriginal; } public void setTextoOriginal(String textoOriginal) { this.textoOriginal = textoOriginal; } public String getTextoEnMayusculas() { return textoEnMayusculas; } public void setTextoEnMayusculas(String textoEnMayusculas) { this.textoEnMayusculas = textoEnMayusculas; } public boolean isRendering() { return rendering; } public void setRendering(boolean rendering) { this.rendering = rendering; } public void pasaAMayusculas(ActionEvent event) { setRendering(true); setTextoEnMayusculas(getTextoOriginal().toUpperCase()); } } es la clase java que va a servir de enlace entre la información y los eventos de la parte cliente y el servidor, y es lo que en terminología JSF conocemos como Managed Bean. Los elementos más significativos de esta clase son: MayusBean • @ManagedBean y @RequestScoped son anotaciones que registran un Managed Bean con la aplicación y le dan un scope de request, respectivamente. El uso de anotaciones es estándar desde la versión 2 de JSF. También sería posible prescindir de las anotaciones y declarar el bean en el fichero de configuración faces-config.xml, como se hacía en versiones anteriores del framework. El atributo name de @ManagedBean asigna el alias con el que va a ser conocido el bean dentro de la aplicación. Si no se declara un atributo name se asigna un alias automático equivalente al nombre de la clase comenzando en minúsculas. • Las propiedades textoOriginal y textoEnMayusculas representan el valor que el usuario introduce en el campo de texto y el que se muestra transformado en mayúsculas, respectivamente. La propiedad rendering se usa para determinar si este último valor se muestra o no. • El método pasaAMayusculas(ActionEvent event), que en la página facelet está definido como un actionListener es invocado cuando se pulsa el botón dibujado en la página. Su función es modificar la propiedades rendering y textoEnMayusculas para que el mensaje en mayúsculas sea mostrado cuando se renderice la respuesta. Eventos y oyentes JSF La especificación JavaServer Faces define tres tipos de eventos: eventos de aplicación, eventos de sistema y eventos de modelado de datos. Los eventos de aplicación son locales a una aplicación y son generados por componentes de la página. Un objeto Event identifica y almacena información sobre el componente que generó el evento. La aplicación proporciona métodos de respuesta para los eventos que quiera tratar y los asocia a los componentes que generan dichos eventos. Cuando el usuario interacciona con la UI, por ejemplo pulsando un botón, se lanza un evento. Este hecho causa que la implementación JavaServer Faces invoque el método oyente que procesa ese evento. JavaServer Faces trabaja con dos tipos de eventos de aplicación: eventos de acción y eventos de cambio de valor. Un evento de acción (javax.faces.event.ActionEvent) se lanza cuando el usuario activa un componente que implementa el interfaz ActionSource. Estos componentes incluyen botones y enlaces. Un evento de cambio de valor ( javax.faces.event.ValueChangeEvent) sucede cuando el usuario modifica el valor de un componente representado por UIInput o alguna de sus subclases. Un ejemplo sería al seleccionar un check box, acción que modifica el valor del componente a true. Los tipos de componente que generan este tipo de eventos son UIInput, UISelectOne, UISelectMany y UISelectBoolean. Los eventos de cambio de valor se lanzan únicamente si no se producen errores de validación. Dependiendo de si el valor de la propiedad immediate del componente que lanza el evento es true o false, los eventos de acción pueden ser procesados durante las fases Invoke Application o Apply Request Values, y los eventos de cambio de valor durante las fases Process Validations o Apply Request Values (ver más adelante la sección sobre el ciclo de vida de una página JSF). Si el valor de esta propiedad es true, en ambos casos los eventos serían procesados durante la fase Apply Request Values (por defecto es false). Un evento de sistema es generado por un Object, y no por un componente. Son generados en momentos predefinidos durante la ejecución de la aplicación. Un evento de modelado de datos sucede cuando una nueva fila de un componente seleccionada. UIData es Hay dos formas de configurar una aplicación para que reaccione a eventos de aplicación: • Implementar un método de un managed bean para que gestione el evento y utilizar EL para referirnos a él desde el atributo apropiado de la etiqueta del componente. • Implementar una clase event listener que maneje el evento y registrar este oyente con el componente, anidando una etiqueta f:valueChangeListener o f:actionListener en la etiqueta del componente. Implementación de oyentes como métodos de beans Para implementar un oyente que reaccione a un evento como método de un bean, necesitamos declarar en el elemento que lanza el evento un atributo actionListener o valueChangeListener que enlace con un método de un bean que responda a ese evento. Un ejemplo de action listener por método podría ser el siguiente: - facelet: - managed bean: public void pasaAMayusculas(ActionEvent event) { setRendering(true); setTextoEnMayusculas(getTextoOriginal().toUpperCase()); } Como ya sabemos, un método actionListener debe devolver void y recibir un objeto javax.faces.event.ActionEvent. Este objeto Event proporciona información sobre el evento, por ejemplo, la fase en la que se ha lanzado el evento o el componente que lo lanzó. Veamos ahora un ejemplo de valueChangeListener como método de bean: - facelet: - managed bean: public void nuevoRBSeleccionado(ValueChangeEvent event) { int actualValue = (Integer) event.getNewValue(); switch (actualValue) { case 0: mensajeFavorito = "Mi color favorito es el ¡rojo!"; break; case 15: mensajeFavorito = "Mi canción favorita es Nutshell"; break; case 22: mensajeFavorito = "Mi libro preferido es... no sé... hay tantos..."; break; } } En este ejemplo además de los atributos value y valueChangeListener declaramos layout, para que los radio button se muestren en una columna en vez de en una fila, y onchange, para que al seleccionar un radio button nuevo se envíe el formulario. Por otra parte el método oyente hace uso del objeto event recibido para recuperar el nuevo valor y actuar en consecuencia. No podríamos consultar directamente la propiedad asociada al componente porque, según el ciclo de fases de una petición JSF (ver capítulo correspondiente), en el momento en que se procesan los eventos de cambio de valor las propiedades del modelo (bean) aún no están actualizadas, por lo que la propiedad asociada (radioBtSelected) aún contendría el valor antiguo. Es posible modificar este comportamiento configurando el método oyente para procesar el evento en una fase más avanzada y así asegurarnos que la propiedad ya se encuentra actualizada. Esta técnica la analizaremos en el capítulo dedicado al ciclo de vida de una página JSF. Eventos Action y navegabilidad Un evento action se produce al pulsar un botón o un hiperenlace. Además de responder a dicho evento, la aplicación puede elegir entre navegar a otra página o permanecer en la página original. Ya hemos visto un ejemplo de implementación de un ActionListener en nuestra primera aplicación de ejemplo, donde definíamos un componente botón que lanzaba un evento al ser pulsado: este código registra un método oyente con el componente que será invocado cuando se pulse el botón. public void pasaAMayusculas(ActionEvent event) { setRendering(true); setTextoEnMayusculas(getTextoOriginal().toUpperCase()); } Éste es el método ActionListener que responde al evento Action. Un método ActionListener debe ser público, devolver void y recibir un objeto javax.faces.event.ActionEvent, que puede ser usado para obtener información acerca del evento. Por otra parte, también podemos declarar métodos Action que respondan a eventos pero que utilizamos para navegar entre páginas de la aplicación. Un método Action es un método público con o sin parámetros que devuelve un String. Este String se utiliza para determinar la página a la que navegaremos cuando se complete el procesamiento de la petición, bien de forma directa (el objeto String representa el nombre de un recurso físico) o mediante una referencia al modelo de navegación declarado en los ficheros de configuración de JSF: Fichero .xhtml: ManagedBean: public String salir() { accesosAPagina++; return "index"; } En este caso se está lanzando un evento Action que ejecuta el método salir() del bean sesBean. Este método realiza una tarea y devuelve la página .xhtml que va a representar el resultado. index puede ser el nombre real de la página (index.html) o un alias definido en la sección de reglas de navegación del fichero faces-config.xml. Un ejemplo de evento action con parámetros sería el siguiente: #{user.id} #{user.name} #{user.email} … public void edit(User user) { this.user = user; this.edit = true; } Reglas de Navegación La navegación entre las diferentes páginas de una aplicación JavaServer Faces, como elegir la siguiente página a mostrar tras la pulsación de un botón o un hiperenlace, se define mediante una serie de reglas. Estas reglas de navegación pueden ser implícitas o definidas explícitamente en nuestro fichero de configuración. Cada regla de navegación especifica cómo navegar desde una página a otras. La implementación JavaServer Faces elige la regla de navegación apropiada en función de la página que se muestra en ese momento. Tras elegir la regla de navegación apropiada, la elección de la siguiente página depende de dos factores: 1. El método action invocado por el componente pulsado 2. El resultado lógico referenciado por la etiqueta del componente o devuelto por el método action /login.xhtml #{loginForm.login} success /storefront.xhtml #{loginForm.login} failure /login.xhtml En esta regla de navegación estamos definiendo dos posibles navegaciones desde login.xhtml. La primera daría como resultado la página storefront.xhtml si el String devuelto por el método action #{loginForm.login} es success. La segunda mostraría de nuevo login.xhtml, si el String devuelto por el método action #{loginForm.login} es failure. Cada elemento navigation-rule corresponde a una única página definida por el elemento opcional from-view-id. Esto significa que cada regla define todos los caminos de navegación posibles desde una página en particular. Si no existe el elemento from-view-id, las reglas de navegación definidas en ese elemento navigation-rule se aplican a todas las páginas de la aplicación. El elemento fromview-id permite también el uso de comodines. Por ejemplo, este elemento from-view-id indica que esta regla de navegación se aplica sobre todas las páginas del directorio books: /books/* Un elemento puede contener cero o más elementos navigation-case. El elemento navigation-case define un conjunto de de criterios de coincidencia. Cuando estos criterios son satisfechos la aplicación navegará a la página definida por el elemento to-view-id. navigation-rule Los criterios de navegación se definen mediante elementos opcionales from-outcome y from-action. El elemento from-outcome define un resultado lógico, como por ejemplo success. El elemento from-action utiliza una expresión de método para referirse a un método action que devuelve un String, que es a su vez el resultado lógico. Los elementos navigation-case se comprueban contra la salida y la expresión de método en el siguiente orden: 1. Si especificamos tanto un valor from-outcome como un valor from-action, la regla se cumple siempre que el oyente ejecutado sea el método especificado en el elemento fromaction y el resultado lógico del método sea el valor especificado en el elemento fromoutcome. 2. Si sólo se especifica un valor from-outcome, la regla se cumple si este valor coincide con el resultado lógico devuelto por el action que se invoque (ya sea el resultado de un método o el valor del atributo action del componente). 3. Si sólo se especifica un valor método especificado. from-action, la regla se cumple si el oyente action Cuando la regla se cumple, la página dibujada es la definida por el elemento to-view-id. es el Componentes y etiquetas JSF Cuando construimos una página JSF utilizamos una serie de etiquetas que al ser procesadas por el servidor generan un árbol de componentes que representan cada uno de los objetos definidos en la página. Cada etiqueta JSF está asociada a un componente + un renderer que dibuja el componente en la página resultado. Al separar el componente de su renderer permitimos al usuario personalizar el dibujado de los componentes, o utilizar el mismo componente con diferentes renderers para distintas etiquetas (por ejemplo, el componente UICommand está asociado a las etiquetas h:commandButton y h:commandLink, y sus renderers respectivos dibujan un botón o un hiperenlace, respectivamente). Los componentes estándar existentes en la arquitectura son los siguientes: • • • • • • • • • • • • • • • • • • • UIColumn: Representa una columna de datos de un compontente UIData. UICommand: Representa un control que lanza eventos action. UIData: Representa un enlace de datos a una colección de datos representada por una instancia javax.faces.model.DataModel. UIForm: Representa un formulario que se presenta al usuario. Sus componentes hijas representan (entre otras cosas) los campos de entrada a incluir cuando el formulario se envía. Este componente es análogo a la etiqueta form en HTML. UIGraphic: Muestra una imagen. UIInput: Componente que recibe datos introducidos por el usuario (por ejemplo desde un campo de texto). Es una subclase de UIOutput. UIMessage: Muestra un mensaje de error en función del idioma del cliente. UIMessages: Muestra un conjunto de mensajes de error en función del idioma del cliente. UIOutcomeTarget: Muestra un hiperenlace bien como un hiperenlace o como un botón. UIOutput: Muestra datos en la página. UIPanel: Gestiona la apariencia de sus componentes hijos. UIParameter: Representa parámetros de substitución. UISelectBoolean: Permite al usuario establecer un valor booleano en un control seleccionando o deseleccionando éste. Esta clase es hija de UIInput. UISelectItem: Representa un elemento de un conjunto de elementos (por ejemplo en una lista desplegable). UISelectItems: Representa un conjunto completo de elementos. UISelectMany: Permite a un usuario realizar selecciones múltiples de entre un conjunto de elementos. Es hija de UIInput. UISelectOne: Permite a un usuario seleccionar un elemento de entre un conjunto de elementos. Es hija de UIInput. UIViewParameter: Representa los parámetros de una request. Es hija de UIInput. UIViewRoot: Representa la raíz del árbol de componentes. Estos componentes, como ya se ha mencionado, están asociados a una o más de las etiquetas JSF que utilizamos para construir páginas. Por tanto, una etiqueta se transforma en un componente en el servidor que a su vez se dibuja en la salida utilizando un renderer. Etiquetas html Las librerías de etiquetas html y core definen las etiquetas JSF con las que construimos una página. Las etiquetas html representan componentes de un formulario y otros componentes básicos, mientras que las etiquetas core sirven de apoyo a la librería html. En la siguiente tabla se resumen las diferentes etiquetas que conforman la librería analizar cada etiqueta por separado: html antes de Etiqueta h:column Función Representa una columna de datos en un componente de datos Dibujada como Una columna de datos en una tabla HTML h:commandButton Envía un formulario al servidor Un elemento HTML Un botón en el que valor puede ser "submit","reset", o "image" h:commandLink Enlaza a otra página Un elemento HTML Un hiperenlace h:dataTable Encapsula un conjunto de datos Un elemento HTML Una tabla que puede ser construida dinámicamente h:form Representa un formulario Un elemento HTML Sin apariencia h:graphicImage Muestra una imagen Un elemento HTML Una imagen h:inputFile Permite la subida de ficheros Un elemento HTML h:inputHidden Permite incluir un campo oculto en un formulario Un elemento HTML Un campo de texto con un botón Browse... Sin apariencia h:inputSecret Permite al usuario incluir un campo de texto sin Un elemento HTML h:inputText Permite al usuario incluir un campo de texto Un elemento HTML Un campo de texto h:inputTextarea Permite al usuario incluir un campo de texto multilínea Un elemento HTML