Está en la página 1de 148

JSF (Java Server

Faces)

Introduccin
Actualmente la mayora de las
aplicaciones se distribuyen por Internet.
Casi todos los accesos clientes se hacen a
travs de Web.
Cada vez hay mas clientes especficos con
dispositivos y pantallas diferentes.
El modelo de programacin Web actual
est basado en documentos no basados
en pantallas de interaccin.

Aportaciones de JSF

JSF logra la unin entre los cliente Web actuales y


el modelo tradicional de componentes.
Logra separar la renderizacin del
componente.
Logra desplazar la interaccin del usuario con el
programa al modelo tradicional de eventos.
JSF es la evolucin estndar de Struts, por
los mismos que realizaron Struts.
Es un estndar claro y potente para poder hacer
aplicaciones visuales mas potentes.

Arquitectura

Nos da Renderizacin, rbol de componentes


visuales, validadores, conversores y
eventos y javabeans.
Nos aporta un ciclo de vida claro estndar.
Nos permite configurar y definir
externamente el flujo de pantallas, la
navegacin.
Nos permite modificar o incorporar componentes
bsicos propios en la arquitectura.
Por ejemplo un ciclo de vida propio

Relacin entre JSF y JSP

Aporta tags para funcionar sobre jsps.


Se podra usar JSF en otros entornos diferentes a
jsp.
Tenemos una librera estndar de JSF-Html para
crear aplicaciones web.
Nos da un nivel de informacin independiente
de estar en un contenedor web-servlets o un
contenedor basado en portlets.
Retrasa la renderizacin hasta el ltimo momento
para poder renderizar con toda la informacin
bien preparada.
Nos permite crear componentes propios para
reutilizar.
JSF tiene un Servlet como entrada de las
llamadas a su arquitectura.

Elementos
Se necesita configurar un servlet de JSF
para enlazar con el contenedor Web.
Se basa en un fichero de configuracin,
por defecto faces-config.xml
Qu gestionamos en el faces-config?

Componentes (Edit/ Label/ ComboBox).


Validadores.
Conversores.
Beans (Java Beans).
Navegacin
Aspectos avanzados...

Configurando JSF:
Descriptor web.xml

Debemos registrar el servlet.


javaxfaces.webapp.FacesServlet

Tenemos que hacer el servlet-mapping de


las uris que vamos a tratar con JSF.
Normalmente de tipo
/facesl*
*.faces
*.jsf

Parmetros de
Configuracin

Se pueden configurar los siguientes parmetros


globales (context-param):

javax.faces.CONFIG_FILES indicando una lista relativa


a nuestro contexto donde estn los archivos de
configuracin de JSF. Por defecto carga /WEB-lNF/facesconfig.xml.
javax.faces.DEFAULT_SUFFIX indica el sufijo por
defecto de recursos conteniendo componentes JSF,
por defecto . jsp.
javax.faces.LIFECYCLE_lD instancia de LifeCycle a usar
por JSF por defecto LifecycleFactory.DEFAULT_LIFECYCLE.
javax.faces.STATE_SAVING_METHOD La localizacin
donde se va a guardar la informacin de estado:
server o client.
Por defecto server en el HttpSession

El cerebro de la bestia:
Faces-config.xml

La etiqueta principal es <faces-config>.


Podemos tener mas de un archivo de
configuracin.
Podemos configurar:

Java beans.
Registrar validadores propios.
Registrar conversores propios.
Configurar reglas de navegacin.
Registrar Renders.
Registrar componentes propios.

Taller prctico Hola Mundo con


Java Server Faces
Partimos de piloto 0.0, entorno de trabajo
basado en Maven2 y generado mediante el
arquetipo para MyFaces.
Lo modificamos para que:

Aparezca una nueva pgina welcome.jsp con un


mensaje de Hola Mundo
Index.jsp redirija mediante
response.sendRedirect(...) a welcome.jsf ?

Probamos la aplicacin. Qu ha ocurrido?

Taller prctico Primera Vista


JSF
Welcome.jsf no es an una vista vlida JSF.
En JSF todas las vistas deben estar
contenidas en un elemento f:view:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>


<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<f:view>
...
</f:view>

Por qu? Encapsular la JSF en el


componente vista.

Configuracin de Beans

Permite declarar los beans que van a ir


instanciando automticamente y en el
scope que se van a a encontrar.
Configurar propiedades de los beans.
Poner el valor de una propiedad de un bean al
resultado de la evaluacin de un mtodo
value-binding.
Scopes:

request.
Session.
application.
none.

El bean es inicializado cada vez que es referenciada


y no se guarda en ningn scope.

Ejemplo de Declaracin de
Bean
<managed-bean>
<managed-bean-name>NA</managed-bean-name>
<managed-bean-class>model.ImageArea</managed
-bean-class>
<managed-bean-scope>application</managed-beanscope>
<managed-property>
<property-name>shape</property-name>
<value>poly</value>
</managed-property>
..

</managed-bean-name>
</managed-bean>

Taller prctico: Mi primer Bean


en JSF

Vamos a inyectar nuestro primer bean en


JSF:
En primer lugar, creamos la clase
es.uniovi.si.UsuarioBean con una propiedad
nombre
Lo declaramos en el faces-config.xml como bean
usuario, inicializando su propiedad nombre con
la cadena Invitado.

<managed-bean>
<managed-bean-name>usuario</managed-bean-name>
<managed-bean-class>es.uniovi.si.UsuarioBean</managed-beanclass>
<managed-property>
<property-name>nombre</property-name>
<value>invitado</value>
</managed-property>

Taller prctico: Mi primer Bean


en JSF

Creamos una nueva vista entrada.jsp y, dentro,


mostramos la propiedad nombre del bean usuario
mediante el componente de salida:

Hola <h:outputText value="#{usuario.nombre}"/>,


bienvenido a mi sitio web.<br>
Probar

a acceder mediante piloto/entrada.jsf


Funciona?
Acceder ahora mediante piloto/entrada.jsp Y
ahora?
Quitar ahora f:view y probar con entrada.jsf.
Funciona?
Resuelto en piloto 1.0.

Botones: UICommand
Realiza una accin al ser activado.
Propiedades bsicas:

Action String o method-binding al mtodo que


devuelve ese String. EL String es usado por el
NavigationHandier para determinar la pagina
siguiente de acceso.
actionListener para escuchar los eventos de
accin

UICommand

Dos tipos de etiquetas bsicas


commanButton representa un botn
<h:commandButton ../>
commandLink representa un elemento de accin
en formato link (con <a></a>) .
La etiqueta ha de contener una etiqueta outputText
para representar donde el usuario clickea para
generar el evento

UInput

Representa los campos de entrada.


En el renderizador de Html tenemos varios tags

inputHidden representa un campo hidden


inputSecret representa a un campo password
inputText
inputTextArea

Suelen tener asociados elementos en las


siguientes
propiedades

Converter Identifica el conversor de datos a utilizar.


Validatos method-binding a la validacin.
valueChangeListener method-binding para escuchar los
cambios de valor

Formularios en JSF
Cuando apliquemos JSF, tenemos que
ceirnos a sus reglas y utilizar sus etiquetas
en lugar de las etiquetas estndar HTML.
stas implementan ms lgica por detrs
que nosotros no vemos pero que nos ahorra
trabajo.
Ejemplo de formulario en JSF:

<h:form>
<h:inputText value="#{usuario.login}"/>
<h:commandButton value="Login" action=?"/>
</h:form>

Taller prctico: Mi primer


formulario

Editamos welcome.jsp y aadimos lo


siguiente:

<h:form>
<h:inputText value="#{usuario.nombre}"/>
<h:commandButton value="Enviar"
action=entrada.jsf"/>
</h:form>

Accedemos a la aplicacin y pulsamos el


botn... Qu ocurre?
Examinamos el cdigo fuente. Adonde
apunta el formulario? Por qu?

Adnde va mi request?
En JSF, TODAS las peticiones van a la propia
pgina. Entonces. Dnde est el truco?
El servlet mapping hace que el controlador
caputure TODAS las peticiones que
concuerden con la extensin *.jsf
Lo que debemos poner en el campo action
de un componente de comando (ntese que
no es a nivel de formulario) es la accin que
se desea disparar
Cmo se navega entonces? Estableciendo
el mapa de navegacin en el controlador.

Navegacin

Permite configurar cual ser la siguiente pagina despus de


pulsar un boton o link.
Cada regla define como navegar desde una pgina
hacia otro conjunto de pginas.
La siguiente pagina depende del mtodo action sobre
el que se haya pinchado y la salida lgica que de la
etiqueta referenciada.
Salidas tpicas:
success:

todo ocurri correctamente.

Failure:

hubo algo mal, ir a una pgina de error.

Logon:

el usuario necesita logearse primero, IR a pagina de logon

No result:

la bsqueda no encontr nada. Ir a la pagina de bsqueda de nuevo

Elementos de Navegacin

From-view-id

Indica la pgina origen de la request.

From-action

indica el action del que procede y que da su valor.

From-outcome

Representa el evento que dispara la transicin.

To-view-id

indica el id de la vista a la que pasamos

Ejemplo: Navegacin
<navigation-rule>
<from-view-id>/logonjsp</from-view-id>
<navigation-case>
<from-action>#{LogonForm.logon}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/storefrontjsp</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{LogonForm.logon}</from-action>
<from-outcome>failure</from-outcome>
<to-view-id>/logon.jsp</to-view-id>
</navigation-case>
</navigation-rue>

Taller prctico: Enlazando


pginas

Vamos a establecer una regla de


navegacin en el faces-config.xml que
determine que cuando se dispara la accin
login desde la pgina welcome.jsp el
controlador nos debe redirigir a entrada.jsf:

<navigation-rule>
<from-view-id>/welcome.jsp</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/entrada.jsf</to-view-id>
</navigation-case>
</navigation-rule>

Recordad modificar el formulario para que


ejecute la accin login. Funciona?

Taller prctico: Enlazando


pginas
Problema: El bean aparece siempre con el
mismo valor. Por qu?:
El scope por defecto de los beans es page, y
nosotros no hemos establecido ninguno
diferente. Editar el faces-config.xml y forzar
que el bean-scope sea request.
Volver a probar la aplicacin.
Resuelto en piloto 2.0

Ms de beans...Bean con
Binding

Con #{expresion languaje} podemos


referirnos a los mtodos, propiedades
y elementos

<managed-bean>
<managed-bean-name>customer</managed-bean-name>
<managed-bean-class>CustomerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>areaCode</property-name>
<value>#{initParam.defaultAreaCode}</value>
</managed-property>
.
</managed-bean>

Inicializacin de una Bean con un


Map

Es un Map de Collections, se puede especificar la clase


que hace de llave
<managed-bean>
<managed-property>
<property-name>prices</property-name>
<map-entries>
<map-entry>
<key>My Early Years: Growing Up *7</key>
<value>30.75</value>
</map-entry>
<map-entry>
<key>Web Servers for Fun and Profit</key>
<value>40.75</value>
</map-entry>
</map-entries>
</managed-property>
</managed-bean>

Arrays y Listas de
Propiedades
<managed-bean>
.
<managed-property>
<property-name>books</property-name>
< list-entries >
<value-class>java.lang.String</value-class>
<value>Web Servers for Fun and Profit</value>
<value>#{myBooks. bookld [3]}</value>
<null-value/>
</ list-entries >
</managed-property>
</managed-bean>

Interactuando con el
modelo
Cmo hacemos que nuestras vistas
interacten con el modelo?
Sabemos como forzar a que JSF invoque un
mtodo get o set sobre un bean, luego
Implementando lgica en los accessors?
No, sera desnaturalizar el mtodo.
Alternativa: Navegacin dinmica

Navegacin dinmica

En el ejemplo que hemos visto, el botn de


commando dispara una accin que, tal y como
hemos configurado, nos redirige de
terminantemente a otra vista.
En las aplicaciones reales, la redireccin
depender del resultado de la interaccin con el
modelo. Ejemplo hago login y:
Si es correcto, paso a la pgina de entrada
Si no, vuelvo a la pgina de login y muestro un error.

Para esto necesito:


Elementos donde implementar la lgica decide la
navegacin
La posibilidad de establecer las diferentes transiciones en
base al resultado.

Navegacin dinmica
Para implementar navegacin dinmica,
debemos utilizar en el elemento de
comando que hace submit una expresin de
mtodo.
Ejemplo:

<h:commandButton label="Login"
action="#{loginController.verifyUser}"/>

En este caso, al pulsar el botn se invocar


el mtodo verifyUser del bean dado de alta
como loginController.

Navegacin dinmica
Cmo se determina el destino tras ejecutar
un mtodo de bean?
Desde el bean:

if (...)
return "success";
else
return login-error";

El bean dispara acciones en base a las


cuales se determinar cual ser la siguiente
vista.

Navegacin dinmica
<navigation-rule>
<navigation-case>
<from-action>#{loginController.verifyUser}
</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/consultaLibros.faces</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{loginController.verifyUser}
</from-action>
<from-outcome>login-error</from-outcome>
<to-view-id>/login.faces</to-view-id>
</navigation-case>
</navigation-rule>

Taller prctico: Preparando el


login

Vamos a implementar e inyectar un bean


que se encarge de nuestro futuro proceso
de login. Para eso:
Aadimos una propiedad password al bean
usuario y completamos el formulario de la
pgina welcome para que se recoja la contrasea.
Creamos es.uniovi.si.LoginAction tal que:
Contenga una propiedad de tipo UsuarioBean
Tenga un mtodo login que:
Si usuario=contrasea=admin entonces dispare
success
Si no, dispare login-error.

Establecemos la navegacin en el facesconfig.xml

Beans Asociados Ms
inyeccin de dependencias
<managed-bean>
<managed-bean-name>customer</managed-bean-name>
<managed-bean-class>com .mycompany.mybeans.CustomerBean</managed-beanclass>
<managed-bean-scope> request </managed-bean-scope>
<managed-property>
<property-name>mailingAddress</property-name>
<value>#{addressBean}</value>
</managed-property>
<managed-property>
<property-name>streetAddress</propertyname>
<value>#{addressBean}</value>
</managed-property>
<managed-property>
<property-name>custom erType</property-name>
<value>New</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>addressBean</managed-bean-name>
<managed-bean-class>com .mycompany.mybeans.AddressBean</managed-beanclass>
<managed-bean-scope> none </managed-bean-scope>
<managed-property>
<property-name>street</property-name>
<null-value/>
<managed-property>
</managed-bean>

Taller prctico Terminando mi


Login
Inyectar el bean usuario en el bean
loginAction en el faces-config.xml
Probar la aplicacin.
Resuelto en piloto 3.0

Taller prctico
Modificar la versin anterior para aadir un
contador que, basndose en el contexto de
la aplicacin, cuente cuantos logins se
realizan en la aplicacin contando todos los
de los usuarios.
Desde donde lo hacemos? En qu clase lo
inyectamos?
Visualizar el resultado del contador en la
pgina final.

Visin global: Qu nos trae


JSF?
Hasta ahora hemos visto y usado algunos
de los elementos que nos aporta JSF, como
los formularios, los comandos, etc.
Los elementos de JSF se clasifican en:

Componentes JSP
Objetos Implcitos

Componentes JSP

JSF basa sus vistas en un rbol de nodos


visuales.
Los nodos tienen asociados un renderizador que
crea su visualizacin.
Entre llamada y llamada se recrea el rbol de
objetos en el lado servidor.
Hay un conjunto estndar de componentes
base.
Tenemos una implementacin de HTML que
implementa de diversa manera estos
componentes base.
Vamos a ver los componentes base con su reflejo
sobre los componentes Html.

EL Objetos Implcitos

Podemos usar el EL para asociar mtodos y propiedades a los


elementos #{.. .}.
Con el Expresion Languaje de JSF tenemos una serie de objetos
implcitos en el contenedor web estndar:

applicationScope
cookie
facesContext
header
headerValues
initParam.
param
paramValues
requestScope
sessionScope
view

Indica el UIComponent que es raz del rbol para esta llamada

Elementos Visuales
Los componentes han de tener un
constructor vaco para poder instanciarse.
Todo componente visual tiene una
representacin como objeto en el servidor
en una jerarqua nodal.
El renderizador se encargara de generar
su
representacin visual segn convenga.

Elementos Visuales

El paquete visual principal es


javax.facescomponent.
Todo elemento visual forma parte de un rbol
nodal de elementos.
El elemento base de la jerarqua es UIComponent.
El elemento funcional base que hereda de
UIComponent es UIComponentBase.
El elemento raz de un rbol es UIViewRoot.
Todo componente debe especificar constantes
indicando el tipo bajo el cual el componente es
registrado y la familia para seleccionar el render
adecuado.
COMPONENT_TYPE, Component_FAMILY

Propiedades del
UIComponent

Propiedades nodales

getParent.
getChildren.
getChildrenCount.
getViewNode
Nos permite acceder al nodo principal del rbol

Buscar componentes hijo.


Cada componente tiene un Id, bien impuesto o
bien generado.

Propiedades del
UIComponent
Nos permite acceder al FacesContext al
que pertenece el componente.
Todo componente pertenece a una familia
y un renderType, la conjuncin de ambos
determina el render a utilizar.
Casi cada componente UI va a tener una
etiqueta asociada.

getAttibutes nos permite acceder a las


propiedades y atributos del componente

Codificacin de datos

Al crear componentes tenemos que implementar la


codificacin y decodificacin de la informacin.
Decode:
Leemos el dato del request y propagamos su valor.

Encode:

EncodeBegin
EncodeChildren
EncodeEnd
Durante la fase de renderizacin los datos se pasan al lenguaje
de marcado.
En caso de no necesitar tener en cuenta los componentes hijo
solo implementaremos en encodeEnd.

UIView
Es el nodo raz de un rbol de
componentes visuales.
Nos permite poner el locale del rbol.
Hereda de UIBaseComponent.
Tiene asociado un RenderKit:

Es una familia de renders.


Cada render en el RenderKit esta designado por
tipo y familia que renderiza.
Su etiqueta es f:view y su nico atributo
opcional es locale

Libreras de etiquetas

Actualmente hay dos libreras de etiquetas


bsicas:

<%@ taglib uri=http://java.sun.com/jsf/core prefix=f %>


<%@ taglib uri= uri=http://java.sun.com/jsf/html prefix=h %>

Librera de Etiquetas

Los componentes han de estar metidos dentro del un nico


nodo raiz <f:view>
Cuando se realiza un <jsp:import> o <c:include> todos
elementos incorporadas han de meterse en un <f: subview>
<f:subview>

<c:include ...>

</f:subview>

Cualquier texto de plantilla incluido por el include o el import,


actualmente debe meterse dentro de una etiqueta <f:
verbatim>
Cada elemento va a tener los atributos del componente mas
los aadidos por el render.
Con el render de HTML podemos ver que el Componente UIData
tiene una implementaron (por extensin) HTMLDataTable que
contiene los atributos configurables relativos a Html y especficos
del Render

Etiquetas Html

Propiedades usuales:

Id del componente, si no se lo ponemos es generado


automticamente.
lmmediate: si esta a true indica que los eventos,
validaciones y conversiones se realizan en la fase de apply
request en vez de en una fase posterior.
Rendered indica si el componente ha de ser renderizado.
Style especifica el cascading style sheet para la etiqueta.
styleClass especifica el class del CSS (cascading style
sheet).
Value indica el valor del componente, como literal o
enlazado con una propiedad del modelo de informacin.
Binding identifica una propiedad de un bean y asocia la
instancia UI del componente a esa propiedad (set.. .(UI..
A)).
Todos los atributos excepto id y var permiten la
asociacin de value-binding con el Expresion
Lenguaje de Java Server Faces.
#{objeto.propiedad}

UIForm
Representa un form de entrada.
Engloba a todos los componentes que
muestran o recogen informacin.

<h:form>. ..</h:form>

UIData
Representa una tabla de informacin.
<h:dataTable..>...
Tiene UIColumns dentro.
Soporta estar enlazado con una coleccin
de objetos sobre la que itera.
El atributo value indica la coleccin sobre
la que iterar.
El atributo var indica la variable sobre la
que se va a ir guardando el objeto de
datos en cada iteracin.

UIData

Tipos de datos soportados:

Listas y arrays de beans.


Una sla bean.
Un javax.sql.ResultSet y
javax.servlet.jsp.jstl.sql.ResultSet.
javax.sql.RowSet.
Javaxfaces.model.DataModel

Todos los tipos de datos soportados tienen


un Wrapper a DataModel, la
implementacin encapsula nuestro objeto
en el wrapper correspondiente.

Propiedades de UIData

First indica la primera fila a ser mostrada.


Rows indica el nmero de filas a mostrar.
Existen varias propiedades que pueden indicar
listas de estilos para los diferentes elementos:

columnClasses
footerClass
headerClass
rowClass
StyleClass

UIColumn y los facets

Representa una columna de informacin en un


UIData
Cada columna puede tener uno o varios facet
que indicaran las cabeceras y pies de las
columnas

Si se quiere poner mas de un componente dentro de una


facet se ha de usar un panelgroup para embeberlos ya
que facet solo soporta tener un componente hijo.
Un facet se usa para representar un componente que es
independiente de la relacin padre-hijo en el rbol de
elementos.
En el caso de las columnas las cabeceras y pies slo se
pintan una vez, no en cada bucle.

<h:column>

Ejemplo de uso
<h:dataTable value="#{gestionLibrosService.libros}"
var="libro">
<h:column>
<f:facet name="header">
<h:outputText value="Ttulo" />
</f:facet>
<h:outputText value="#{libro.titulo}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Autor" />
</f:facet>
<h:outputText value="#{libro.autor}"/>
...
</h:dataTable>

Taller prctico: Uso del


DataTable

Modificar la versin 3.0 del piloto y:


Crear una clase LibroBean con las propiedades
autor, ttulo, descripcin y precio.
Crear una clase Libreria que contenga un Vector
de LibroBeans almacenados en una propiedad
catalogo
Declarar una librera con al menos 3 libros
diferentes y denominarla liberia
Modificar la pgina entrada.jsp para que muestre
el catlogo de la librera usando un tag
h:dataTable.
Qu scope tendrn que tener los libros? Y la
librera?
Resuelto en piloto 4.0

Ciclo de Vida de JSF

Cada llamada que lleva a un JSF tree pasa por


una serie de fases determinadas que crean su
ciclo de vida.
Existen tres tipos de escenarios posibles:
Una peticin sin JSF genera una respuesta con JSF.
Una peticin con JSF genera un respuesta con JSF.
Una peticin con JSF genera una respuesta sin JSF.

A su vez la aplicacin tambin puede recibir


peticiones sin JSF que generen respuestas sin JSF

FaceContext

Toda llamada o request tiene asociado un


FaceContext y al hilo de llamada.
El FaceContext solo debe existir durante la
request hasta que se llame a su mtodo release.
No se le debe referenciar por un objeto que tenga
una vida mas larga que la request .
Contiene toda la informacin relativa al
estado en la request y la renderizacin de la
respuesta.
Encapsula el elemento raz visual ViewRoot.

FaceContext

Encapsula los posibles mensajes.


Nos permite acceder al Singleton de Application.
Encapsula ResponseWriter -salida de
cracteres- y ResponseStream salida
binaria-. Como flujos de escritura para los
renderizadores.
Nos permite acceder a ExternalContext:
Nos da acceso al entorno independientemente de estar
en un contenedor de servlets o de portlets.
Accedemos a todo el entorno de informacin que
tendramos como servlet.

Fases Estndar

Restore View

Restore View

El servidor recibe una llamada y recompone los objetos de


la vista en el servidor.
Examina si FacesContext tiene un UIViewRoot en caso de
tenerlo:
Le asigna el locale correspondiente
(internacionalizacin).
Para cada valor en el rbol mira si tiene un valuebinding
asociado a binding y si lo tiene llama a setValue() pasando la
instancia en donde se encontr.
No se realizan mas acciones.

Se crea el viewID de la URI y de los valores de prefijo:


ViewHandler.DEFAULT_SUFFIX_NAME

Restore View

Llaman a viewHandler.restoreView() pasando la


instancia FacesContext asociada a la llamada y el
viewID, consiguiendo el UIViewRoot como
respuesta:
En caso de devolver null no haba vista asociada por lo
que se crea una y se pasa al renderResponse:
se llama a ViewHandler.createView() y a
FacesContext .renderResponse()

Si la peticin no contiene parmetros de llamada ni datos


en POST se llama a renderResponse

Restore View
Se almacena el UIViewRoot en el
FacesContext.
Se determina el valuebinding para cada
atributo binding y se llama al setValue.
Al final de esta fase tenemos recuperado
el viewRoot que haba y si acaso se ha
creado uno nuevo.

Apply Request Values

Apply Request Values


Da la oportunidad a los componentes
a actualizar sus valores a los valores
que llegan de la request.
Se llama al mtodo processDecodes() de
todos los componentes del rbol
UIViewRoot.
Los componentes que implementan
ActionSource que reconocen que fueron
activados encolan su evento.

Estos eventos son notificados al final de esta


fase

Apply Request Values

Los componentes que implementan


EditableValueHolder que tienen la
propiedad immediate a true realizan la
conversin y validacin. lncluyendo el
potencial lanzamiento del evento
ValueChange.
Normalmente immediate esta a false esto
ocurre posteriormente en la fase de Process
Validations

Posibilidades de cambio de
Fase

Todo error producir un mensaje que se encolara


en el FaceContext, y el componente que la lanza
ser marcado como invalido.
En cualquier momento si nuestra lgica en los
decode, o en los eventos llama a
responseComplete en FacesContext. Se termina
inmediatamente el procesado del request.
Si se llama a renderResponse en el FacesContext
se transfiere el control a la fase de Render
Response.
En caso contrario pasamos a la fase de Process
Validations

Process Validations

Process Validations
Se procesan las validaciones llamando
a processValidators.
Cualquier fallo en la validacin mete un
mensaje de error en el FacesContext.

Y la propiedad valid del componente se pone a


false.

En cualquier validador puede llamar a


responseComplete o a renderResponse de
FacesContext.

Update Model Values

Update Model Values

Llegados a esta fase se asume que los


contenidos son sintcticamente y
semnticamente correctos.
Se asume que el valor local de los
componentes ha sido actualizado.
Es el momento de actualizar los datos del
modelo de la aplicacin.
Esto se produce recursivamente llamando a
UlComponent.processUpdates.
La actualizacin dentro de un componente se
realiza llamando al mtodo updateModel.

Update Model Values


Durante la actualizacin los eventos son
encolados hasta la finalizacin de la fase
donde se procesan.
Al finalizar esta fase los valores del
modelo de datos han sido actualizados y
los valores de los componentes han sido
vaciados.
Cualquiera de nuestros mtodos podra
llamar a responseComplete o a
renderResponse.

Invoke Application

Invoke Application
Si se alcanza esta fase se asume que la
actualizacin del modelo ha sido
completada.
Se llama al mtodo processApplication de
UIViewRoot.
Se llama a todos los eventos encolados
con
phaseId.INVOKE_APPLICATION.
Excepcionalmente se podra llegar a
cambiar el actionListener por defecto con
setActionListener

Render Response

Render Response

Hace que la respuesta sea renderizada al


cliente.
Hace que el estado de la respuesta sea
guardado para ser procesado en llamadas
sucesivas.
Cuando un componente de rbol es seleccionado
para renderizarse se llama a su mtodo de
encodexxx().
Para los elementos que implementan ValueHolder
se ha de producir su conversin.
Antes de completarse el estado de la vista ha de
ser guardado usando los mtodos de la clase
StateManager.
Esta informacin ha de estar disponible para que Restore
View pueda acceder a ella en sucesivas llamadas.

Backing beans
Son beans que no responden a entidades,
sino a agrupaciones que datos que por
motivos prcticos, nos puede interesar
procesar juntos, a nivel no de valores sino
de componentes.
Es imprescindible para validaciones en las
que se han de comprobar relaciones entre
componentes.
Ejemplo: Representacin de formularios

Backing beans

Si queremos hacer un backing bean para un


formulario de cambio de usuario en sesin que
muestra y recibe informacin al mismo tiempo,
por ejemplo:

Public class ChangeSessionForm


{
UIInput newUser;
UIOutput oldUser;
//getters and setters...
}
...

En la JSP:
<h:outputText binding="#{changeSessionForm.oldUser}"/>

Lo que le pasa JSF al formulario al hacer binding no


es el valor del componente, sino su referencia.

Taller prctico: Uso de backing


beans

Vamos a alterar el proceso de login para


utilizar es.uniovi.si.backing.LoginForm como
backing bean. Para ello:
Declaramos dos propiedades UIInput (login y
password)
Declaramos el bean como loginForm y se lo
inyectamos al LoginAction
Hacemos el enlazado entre los campos del
formulario y modificamos adecuadamente la clase
LoginAction para que partir de ahora recupere los
valores del formulario.
Resuelto en piloto 5.0

Ms elementos UIInput...
Los elementos de formulario que muestran
elementos entre los que seleccionar
(combo, radio, listas, etc) comparten modo
de funcionamiento.
La entrada de datos debe ser una coleccin
de elementos SelectItem.
Ej:

New SelectItem(010,The Matrix);

Cmo se conecta con el formulario?

UISelectBoolean
Etiqueta h:selectBooleanCheckbox
Representa un estado booleano

UISelectMany

Tres renderizaciones bsicas


selectManycheckbox

Muestra una lista de checkboxes


Value indica el set de elementos seleccionados
actualmente.
Layout indica como se han de poner los checkbox
pageDirection/lineDirection.
Contiene etiquetas selectItem o selectItems
representando a los elementos.

selectManyListBox
selectManyMenu

UISelectOne

Permite seleccionar solo un elemento:


selectOneRadio
selectOneMenu
selectOneListbox

Su contenido son colecciones de Selectltem


o Selectltems

UISelectItems UISelectItem,
UISelectGroup

Nos permiten anidar elementos en los select


f:SelectItem
Un UISelectItems representa a una coleccin de
SelectItem o de SelectItemGroup.
SelectItems permite tomar los datos de Arrays,
Map y Collection de elementos tipo SelectItem o
SelectItemGroup
Javax.faces.modelSelectItem.
Todo Item tiene un Label y un value.

Carga de SelectItems.

Ej: para cargar un combo...


Bean pruebaForm:

Private UIInput propiedadDestino;


public Collection getOpciones()
{
opciones = new ArrayList();
opciones SelectItem(01,Opcin 1"));
opciones SelectItem(02",Opcin 2"));
return opciones;
}

En la jsp:
<h:selectOneMenu
binding="#{pruebaForm.propiedadDestino}">
<f:selectItems value="#{pruebaForm.opciones}"/>
</h:selectOneMenu>

Taller prctico: uso de


combos

Vamos a aadir al formulario de login un


combo con el idioma preferido por el
usuario. Para ello:
Aadimos una propiedad idioma de tipo IUInput al
LoginForm, y un mtodo getIdiomas que retorne
una coleccin de SelectItems con:
es,Espaol
en,English

Lo enlazamos y mostramos lo recibido en el


LoginForm al pulsar el botn.
(Resuelto en piloto 6.0)

Taller prctico: Repasando

Completar piloto 6.0 para:


Aadir un formulario en entrada.jsp con:
Un combo donde se muestre la lista de libros
Un editBox donde se introduzca la cantidad del libro
seleccionado

Un backing bean CarritoForm con un mtodo add


para gestionar el carrito de la compra
Un CarritoBean que resida en sesin y que
encapsule una HashMap. Tendr que tener un
mtodo public List<Entry> getProductos()
que retorne una lista de objetos entry obtenidos
mediante el mtodo entrySet de la HashMap.

Taller prctico: Repasando


Una pgina vercarrito que muestre el estado del
carrito de la compra mediante una tabla, con un
enlace a la pgina anterior:
<h:form>
<h:commandLink action="success">Volver</h:commandLink>
</h:form>

Resuelto en piloto 7.0

Resource Bundles y
Mensajes
En cualquier aplicacin es conveniente evitar tener las
cadenas de texto hardcodeadas en el cdigo fuente de las
pantallas o pginas.
Los resource bundles sirven para seleccionar el mensaje de
error en funcin de la clave, buscndolo en los resource
bundle cargados. En el faces-config:
<application>
<resource-bundle>
<base-name>messages</base-name>
<var>msgs</var>
</resource-bundle>
</application>

Luego los referenciamos mediante EL. Ejemplo:


<h:outputText value="#{msgs.welcome}"/>

El fichero

messages.properties:
welcome=Benvenido a mi pgina web!!!!

Taller prctico
Sobre piloto 7.0...
Creamos messages.properties.
Lo configuramos como fichero de recursos
con el prefijo msgs.
Extraer los mensajes de al menos una de
las vistas, por ejemplo, welcome.jsp.
Probar la aplicacin.
Resuelto en piloto 8.0

Internacionalizacin

JSF aprovecha la externalizacin de cadenas de


texto para implementar la internacionalizacin de
etiquetas.
En la request viaja el idioma preferido del
navegador, representado por el parmetro
LOCALE.
El locale responde a un cdigo estandarizado
(es,en,fr, etc).
Para internacionalizar la aplicacin: un fichero de
recursos por locale:

messages.properties
Messages_en.properties
Messages_fr.properties
...

Taller prctico

Internacionalizar la aplicacin para el ingls.


Para ello:
Creamos un fichero messages_en.properties
copiando el messages.properties.
Traducimos las cadenas de texto al ingls
Para probarlo, establecemos en el navegador el
ingls como idioma por defecto.

Cambio del idioma del usuario


Actualmente se recomienda que el usuario
pueda seleccionar explcitamente el idioma
por encima de lo que diga el parmetro de
idioma preferido del navegador.
JSF permite establecer el locale de varias
formas diferentes:

Cambio del idioma del


usuario
1.

Establecindolo directamente en el facesconfig.xml, el criterio idioma del


navegador prevalece sobre sto.:

<faces-config>
<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>de</supported-locale>
</locale-config>
</application>
</faces-config>

Cambio del idioma del


usuario

2. Establecerlo como parmetro de la


etiqueta f:view:
<f:view locale="de">

Ventaja, podemos establecerlo


dinmicamente
<f:view locale="#{user.locale}"/>

3. Establecerlo por programa


UIViewRoot object:
UIViewRoot viewRoot =
FacesContext.getCurrentInstance().getViewRoot();
viewRoot.setLocale(new Locale("de"));

Taller prctico
Modificar la aplicacin para que el criterio
del idioma que estamos seleccionando al
hacer login cambie el locale de la
aplicacin.
Para verlo reflejado, internacionalizar
alguna de las pginas posteriores al proceso
de login.
Dnde recogemos el locale?
Resuelto en piloto 9.0

Conversores

JSF aporta una coleccin de conversores


predefinidos para tipos de datos estdar.
Converter es el interfaz capaz de hacer
transformaciones string-objeto y objeto-string.

public java.langObject
getAsObject(javax.faces.context.FacesContext context,
javax.faces.com ponent. UlComponent component,
java.lang.String value)
public java.Iang.String
getAsString(javax.faces.context. FacesContext context,
javax.faces.component. UlComponent component,
java.lang.Object value)

Podemos asociar un conversor a un lnput/Output.


El atributo converter indica la clase java que
implementa ese interface.
Tambin se puede anidar dentro de una etiqueta
con f:converter.

Conversores Existentes

Tenemos conversores automticos para los


tipos bsicos:

BigDecimalConverter
BigIntegerConverter
ByteConverter
CharacterConverter
DateTimeConverter
DoubleConverter
FloatConverter
IntegerConverter
LongConverter
NumberConverter
ShortConverter

Conversor de Fecha

f:dateTimeConverter permite hacer conversiones


de
fecha:

datestyle: indica el formato: default, short, medium, long


y full.
locale: indica el Locale, por defecto
FacesContext.getLocale.
pattern: indica el patrn de fecha (dd/MM/yy por ejemplo)
timeStyle: define el formato de hora
timeZone:
type: indica si el string va a contener una fecha, hora o
ambos

Conversor de nmero

F:numberConverter permite controlar


conversiones de numero

currencyCode, currencySymbol, pattern, locale,


minIntegerDigits, maxIntegerDigits,
minFractionDigits, maxFractionDigits.
groupingUsed: boolean indica si la cadena de
salida tiene separadores de agrupamiento.
integerOnly: boolean indica si se va a parsear la
parte entera del valor.
Type: indica si el valor a parsear y formatear es
nmero, moneda o porcentaje

Conversores estndar

El funcionamiento cuando hay un conversor


es el siguiente:

El usuario enva los datos


Se vuelvan al rbol de componentes
Se invocan los conversores
En caso de error,
Se aaden los mensajes de error a la lista global de
mensajes
Se vuelve a mostrar la pgina original y, en caso de
que exista una etiqueta h:messages, se muestran los
errores.

Conversores estndar

Ejemplos:

<h:outputText value="#{payment.date}">
<f:convertDateTime/>
</h:outputText>
<h:outputText value="#{payment.amount}">
<f:convertNumber type="currency"/>
</h:outputText>
<h:inputText value="#{payment.amount}">
<f:convertNumber minFractionDigits="2"/>
</h:inputText>

Renderizado de errores
Cmo muestro los errores de
conversin/validacin?
Si quiero mostrarlos todos juntos:

<h:messages/>

Si quiero mostrar los especficos de un


campo:
<h:inputText id=unidades" label=Unidades"
binding="#{bean.unidades}">
<f:convertNumber integerOnly="true"/>
</h:inputText>
<h:message for=unidades"/>

Taller prctico
Basarse en el ejemplo anterior para aplicar
un conversor para la cantidad de productos
que se aaden al carrito y mostrar los
errores asociados al cambo justo debajo del
mismo.
Probarlo metiendo caracteres en el campo.
Funciona? Cmo sale el mensaje?
Resuelto en piloto 10.0.

Cambiando los mensajes


predefinidos
Lo habitual ser personalizar los mensajes
de error que disparan los validadores, entre
otras cosas, para internacionalizar la
aplicacin
Para ello, en los message-bundles
sobrescribimos los mensajes predefinidos
haciendo referencia a los cdigos de
identificacin de cada mensaje.
Ejemplo:

Ejemplos:
Cdigo

mensaje

javax.faces.converter.Intege
rConverter. INTEGER

{2}: "{0}" must be a number


consisting of one or more
digits.

javax.faces.converter.Intege
rConverter.INTEGER_detail

{2}: "{0}" must be a number


between -2147483648 and
2147483647. Example: {1}

javax.faces.converter.Double
Converter.DOUBLE

{2}: "{0}" must be a number


consisting of one or more
digits.

javax.faces.converter.Double
Converter.DOUBLE_detail

{2}: "{0}" must be a number


between 4.9E-324 and
1.7976931348623157E308.Examp
le: {1}

javax.faces.converter.Boolea
nConverter.BOOLEAN_detail

{1}: "{0}" must be 'true' or


'false'. Any value other
than 'true' will evaluate to

Validadores
JSF permite validar el contenido de
diferentes datos.
Podemos usar el atributo validator para
apuntar al mtodo de una bean que
realiza validacin.
Los validadores se pueden registrar en las
clases que implementan
EditableValueHolder.
En caso de no cumplirse la validacin han
de lanzar ValidatorException coteniendo
un FacesMassage con el error.

Tres tipos de validadores


estndar

La clase DoubleRangeValidator con tag


f:validateDoubleRange:

Valida un valor que puede ser convertido a coma flotante.


Mira que este entre dos valores dados, minimummaximum.

La clase LengthValidator con tag f:validateLength.


Mira que la longitud de la cadena este entre un mnimo y un
mximo

La clase LongRangeValidator con tag


f:validateLongRange
Para valores que se puedan convertir a long.
Mira que este entre dos valores dados.

Validades predefinidos

Parmetros:

Validades predefinidos

Para comprobar que un dato est presente,


no hace falta ningn validador anidado,
basta con establecer el atributo required a
true.

<h:inputText id="card" value="#{payment.card}"


required="truerequiredMessage="#{msgs.campoRequerido}">
<f:validateLength minimum="13"/>
</h:inputText>

Taller prctico
Modificar el piloto anterior para que adems
se requiera el campo cantidad.

Taller prctico

Modificar la welcome.jsp para que:


Los campos login y password sean obligatorios.
La password tenga al menos 3 caracteres
Se visualicen mensajes personalizados e
internacionalizados.

Resuelto en piloto11.0

Taller prctico: Juntndolo


todo

A partir del piloto anterior:

Definir un bean Usuarios (y declararlo como usuario)


que contenga un ArrayList con un UsuarioBean por cada
usuario que queramos en la aplicacin.
Modificar el proceso de login para que el proceso se
realice contra los usuarios del bean Usuarios.
Crear una pgina registro.jsp y un backingbean
RegistroForm con un mtodo registro que reciba login y
password y aada el nuevo usuario al bean usuarios.
Enlazar desde welcome.jsp a registro.jsp con:
<h:outputLink value="registro.jsf">
<f:verbatim>Nuevo usuario</f:verbatim>
</h:outputLink>

Resuelto en piloto 12.0

Gestin de Eventos en JSF


En entornos de desarrollo de tipo
cliente/servidor estamos acostumbrados a
poder asociar eventos de tipo onClick o
onChange a los componentes visuales de la
pantalla.
En Web, dado que trabajamos sobre Http...
Se puede hacer esto?
JSF, al igual que otras plataformas como
.NET simula esto encapsulando el evento en
una request que es enviada al servidor sin
llegar a disparar la accin del
formulario.

Tipos de eventos en JSF

JSF soporta tres tipos de eventos:


Value change events
Disparados por elementos UIInput cuando el valor
que contienen cambia.

Action events
Los disparan los elementos UICommand cuando el
botn o enlace asociado es activado.

Phase Events
Son disparados rutinariamente por el ciclo de vida
JSF.

Value Change Events

Pensados para elementos dependientes en los


formularios. Ej: Combo de paises + combo
provincias.

<h:selectOneMenu value="#{form.country}" onchange="submit()"


valueChangeListener="#{form.countryChanged}">
<f:selectItems value="#{form.countryNames}"/>
</h:selectOneMenu>

Esto dispara el mtodo form.countryNames que


se espera recibir un evento...

public void countryChanged(ValueChangeEvent event) {


FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(new Locale( (String)
event.getNewValue()));
}

El tipo ValueChangeEvent
Mtodo

Descripcin

UIComponent
getComponent()

Retorna una referencia al objeto que


dispar el evento.

Object getNewValue()

Retorna el nuevo valor

Object getOldValue()

Retorna el valor antiguo

Los heredados de FacesEvent...


void queue()

Encola el evento para que sea


disparado al final del ciclo de vida
actual

PhaseId getPhaseId()

Devuelve el id de la fase en la que nos


encontramos.

void setPhaseId(PhaseId)

Marca el evento con el identificador de


la fase en la que fue aadido a la cola.

Taller prctico

Modificar el piloto para que el combo del


idioma que se muestra en la pgina
welcome tenga asociado un manejador de
evento idiomaCambiado en loginForm de
forma que cambie el idioma de la
aplicacin. Para ello:
Asociamos el evento al componente y al
manejador de evento en la jsp.
Implementamos el manejador en loginForm de
forma que establezca el nuevo idioma obteniendo
la referencia al ViewRoot por medio de
FacesConfig.
Resuelto en piloto 13.0

Taller prctico...
Modificar entrada.jsp para que cuando
cambie el combo del formulario, a su
derecha se muestre el valor del libro
seleccionado.
Para ello:

Asociamos el evento onValueChange a un mtodo


productoSeleccionado del CarritoForm
Creamos un objeto UIOutput en la jsp que tome el
valor de un campo de tipo Integer del
CarritoForm.
Resuelto en piloto 14.0

Action Events
Son disparados por los objetos UICommand
cuando se activa el componente
Se invocan durante la fase Invoke
Application

<h:commandLink actionListener="#{bean.linkActivated}">
...
</h:commandLink>

Cuando se activa el componente, el


formulario se enva y el controlador dispara
los eventos.
Entonces... En qu se diferencian de los
actions?

Action listeners vs. Actions

Actions:
Diseados para la lgica de negocio.
Deciden sobre la navegabilidad del sistema

Action listeners:
Orientados a ejecutar lgica de presentacin.
No pueden decidir qu mensaje se enva al controlador.

Los dos tipos de elementos trabajan


coordinadamente cuando el Action requiere
informacin del interfaz de usuario.
Ejemplo: Una imagen enlazada que dependiendo
de la zona pulsada, generar una redireccin u
otra.

Ejemplo de action events

Enlace en la JSP:

<h:commandButton image="mountrushmore.jpg"
actionListener="#{rushmore.listen}"
action="#{rushmore.act}"/>

En el backing bean...
private String outcome;
private Rectangle washingtonRect = new Rectangle(70,30,40,40);
private Rectangle jeffersonRect = new Rectangle(115,45,40,40);
public void listen(ActionEvent e) {
FacesContext context = FacesContext.getCurrentInstance();
String clientId = e.getComponent().getClientId(context);
Map requestParams = context.getExternalContext().getRequestParameterMap();
int x = new Integer((String) requestParams.get(clientId + ".x")).intValue();
int y = new Integer((String) requestParams.get(clientId + ".y")).intValue();
outcome = null;
if (washingtonRect.contains(new Point(x,y)))
outcome = "washington";
...

public String act()


{
return outcome;
}

Taller prctico: Enlazando


action events
En primer lugar, creamos un nuevo mtodo
public void listen(ActionEvent e) en el
CarritoForm que muestre un mensaje por
pantalla demostrando que ha sido invocado.
Lo asociamos al botn de submit del
formulario de la pgina entrada.jsp.
Cul se dispara primero?

Taller prctico.

Extender la versin anterior para:


Desligar al botn de submit del listener
Crear un enlace activo (h:commandLink) que:
no tenga atributo action
Est asociado al listener que hemos creado
Se represente con la cadena de texto Incrementa

Modificar el mtodo listen para que cada vez que


se ejecuta, adems de mostrar el mensaje:
Tome el string del UIInput cantidad
Cree un entero y le sume uno
Estableza de nuevo el valor calculado en el
componente cantidad.
Resuelto en piloto 15.0

Event Listener Tags


Hasta ahora hemos asociado los listeners
por medio de los atributos de los elementos
HTML.
Esto mismo se puede realizar utilizando dos
etiquetas:

f:actionListener
f:valueChangeListener

Ventajas sobre la alternativa anterior: Puede


asociar varios listeners diferentes al mismo
elemento.

f:actionListener &
f:valueChangeListener

Diferencias en la aplicacin:
Versin con el atributo

<h:selectOneMenu value="#{form.country}" onchange="submit()"


valueChangeListener="#{form.countryChanged}">
<f:selectItems value="#{form.countryNames}"/>
</h:selectOneMenu>

Versin con f:valueChangeListener:


<h:selectOneMenu value="#{form.country}" onchange="submit()">
<f:valueChangeListener type="com.corejsf.CountryListener"/>
<f:selectItems value="#{form.countryNames}"/>
</h:selectOneMenu>

No es una method
expression sino
una clase!

Clase ValueChangeListener

La clase listener para los eventos de cambio


de valor tiene que implementar una
determinada interfaz:
ValueChangeListener

public class CountryListener implements ValueChangeListener {


public void processValueChange(ValueChangeEvent event)
{
...
}
}

El controlador invoca el mtodo


processValueChange tras cada cambio.

Clase ActionListener

Similar a la anterior:

<f:actionListener type=" com.corejsf. RushmoreListener "/>

Y la clase, implementando la interfaz


ActionListener:

public class RushmoreListener implements ActionListener {


public void processAction(ValueChangeEvent event)
{
...
}
}

Taller prctico
Crear una clase LibroCambiadoListener que
implemente la interfaz ValueChangeListener
Implementar su mtodo
processValueChange para que saque un
mensaje.
Asociarla a la etiqueta del combo de la
pgin entrada.jsp. Ojo! Hay que quitar el
atributo que la liga al otro listener, son dos
alternativas incompatibles!
Resuelto en piloto 16.0

Componentes inmediatos

Problema: En casos como el combo de


cambio de idioma, se nos estn disparando
los validadores que conviven dentro del
mismo formulario. Porqu?

Se disparan los
validadores y
conversores

Se procesan los
eventos

Componentes inmediatos

Si marcamos un componente como


inmediato:

<h:selectOneMenu binding="#{loginForm.idioma}" onchange="submit()


valueChangeListener="#{loginAction.idiomaCambiado}" immediate="true">

Componentes inmediatos

Problema:
El ciclo de vida sigue si rumbo normal tras la validacin y
procesado de eventos de los componentes inmediatos

Solucin:
Cortamos el flujo desde el listener y forzamos la renderizacin
de la respuesta (el atajo en el grfico anterior)
context.renderResponse();

Taller prctico

Hacerlo sobre la versin actual del piloto para el cambio de


idioma en el login

Comandos inmediatos?

En el caso de los comandos, tambin podemos hacerlos


inmediatos, pero no hacer falta forzar el renderizado
porque al terminar van directos a dicha fase.

Envo de informacin desde la


Interfaz de Usuario al Servidor.

Supongamos que queremos hacer la


internacionalizacin con dos banderas, una por
idioma, haciendo que ambas sean
commandLinks:

<h:commandLink action="#{localeChanger.englishAction}" immediate="true">


<h:graphicImage value="/british_flag.gif"/>
</h:commandLink>

En el servidor:

public class ChangeLocaleBean {


public String germanAction() {
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(Locale.GERMAN);
return null;
}
public String englishAction() {
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(Locale.ENGLISH);
return null;
}

Envo de informacin desde la


Interfaz de Usuario al Servidor.

Problema:
Estamos definiendo mtodos que son
prcticamente iguales repetimos lgica- y que en
orientacin a objetos podra ser uno solo
parametrizado.

Solucin:
Envo de informacin desde la interfaz al usuario.
Mtodos:
f:param
f:setPropertyActionListener
f:attribute

<f:param.../>
Nos permite adjuntarle un parmetro a un
componente.
Se comporta diferentemente dependiendo
del tipo de componente:

Si lo usamos en un h:outputText, los distintos


parmetros se usan para rellenar las variables
({0} is bigger than{1}) que se encuentren en el
valor del componente.
Si lo usamos en un UICommand, los parmetros
se aaden como un parmetro de la request.

<f:param...>

Para el ejemplo anterior:

<h:commandLink immediate="true action="#{localeChanger.changeLocale}">


<f:param name="languageCode" value="de"/>
<h:graphicImage value="/german_flag.gif" style="border: 0px"/>
</h:commandLink>

En el servidor:

public String changeLocale() {


FacesContext context = FacesContext.getCurrentInstance();
String languageCode = getLanguageCode(context);
context.getViewRoot().setLocale(new Locale(languageCode));
return null;
}
private String getLanguageCode(FacesContext context) {
Map<String,String> params=context.getExternalContext().getRequestParameterMap();
return params.get("languageCode");
}

Taller prctico: uso de f:param


Crear en LoginForm un nuevo mtodo
idiomaCambiado() que recupere el
parmetro nuevoIdioma de la request y
establezca el nuevo Locale
Aadir dos etiquetas de comando, una por
idioma, a la entrada.jsp, estableciendo
como atributo action (no actionListener!) e
inmediato = true;
Resuelto en trabajo 17.0

<f:attribute...>

Similar, pero en lugar de aadirlo a la request, se


aade como atributo al componente, por lo que
tenemos que usar action listeners (reciben el
componente en el evento!)

<h:commandLink immediate="true actionListener="#{localeChanger.changeLocale}">


<f:attribute name="languageCode" value="de"/>
<h:graphicImage value="/german_flag.gif" style="border: 0px"/>
</h:commandLink>

En el servidor

public void changeLocale(ActionEvent event) {


UIComponent component = event.getComponent();
String languageCode = getLanguageCode(component);
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(languageCode));
}
private String getLanguageCode(UIComponent component) {
Map<String, Object> attrs = component.getAttributes();
return (String) attrs.get("languageCode");
}

<f:setPropertyActionListener...

Desde JSF 1.2, establece una propiedad


directamente en nuestro backing bean...

<h:commandLink immediate="true action="#{localeChanger.changeLocale}">


<f:setPropertyActionListener target="#{localeChanger.languageCode} value="de"/>
<h:graphicImage value="/german_flag.gif" style="border: 0px"/>
</h:commandLink>

En el servidor...

public class ChangeLocaleBean {


private String languageCode;
public String changeLocale() {
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale(new Locale(languageCode));
return null;
}
public void setLanguageCode(String newValue) {
languageCode = newValue;
}
}

Otras cosillas...

Conversores Propios
<converter>
<description>Converter for credit card numbers that
normalizes the input to a standard format</description>
<converter-id>CreditCardConverter</converter-id>
<converter-class> converters Cred itCardConverter
</converter-class>
</converter>

Render Propio
<render-kit>
<renderer>
<component-family>Area</component-family>
<renderer-type>DemoArea</rendere-type>
<renderer-class>renderers.AreaRenderer</renderer-class>
<attribute>
<attribute-name>onmouseout</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
<attribute>
<attribute-name>onmouseover</attribute-name>
<attribute-class>java.lang String</attribute-class>
</attribute>
<attribute>
<attribute-name>styleClass</attribute-name>
<attribute-class>java.lang.String</attribute-class>
</attribute>
</renderer>

Componente Propio
Podemos registrar componentes visuales propios
<component>
<component-type>DemoArea</component-type>
<component-class>components.AreaComponent</component-class>
<property>
<property-name>alt</property-name>
<property-class>java.lang.String</property-class>
</property>
<property>
<property-name>coords</property-.name>
<property-class>java.lang.String</property-class>
</property>
<property>
<property-name>shape</property-name>
<property-class>java.lang.String</property-class>
</property>
<component-extension>
<component-family>Area</component-family>
<renderer-type>DemoArea</renderer-type>
</component-extension>
</component>

UIGraphic
Muestra una imagen.
Propiedades de un, alt (texto alternativo,
normalmente mostrado al pasar el ratn por
encima) y dems relativas al uso comn en
html (en la renderizacin tpica Html).
<h:graphiclmage./>

UIOutput
Indica un dato de salida
Con el Renderizador de Html tenemos

outputLabel
Su atributo for apunta a un id de un campo de entrada
con el que se encuentra asociada la etiqueta

outputLink
Necesita una etiqueta verbatim que muestra el texto
que el usuario clickea para lanzar el link

UIOutput
outputFormat que muestra un mensaje
Permite la utilizacin de java.text.MessageFormat.
Value indica la frase a parametrizar normalmente de un
ResourceBoundle.
Tiene etiquetas de tipo <f:param value...> para indicar
los parmetros del mensaje.

outputText que muestra un texto de una lnea

También podría gustarte