` ` ` `

Actualmente la mayoría de las aplicaciones se distribuyen por Internet. Casi todos los accesos clientes se hacen a través de Web. Cada vez hay mas clientes específicos con dispositivos y pantallas diferentes. El modelo de programación Web actual está basado en documentos no basados en pantallas de interacción.

` ` ` ` `

JSF logra la unión entre los cliente Web actuales y el modelo tradicional de componentes. Logra separar la renderización del componente. Logra desplazar la interacción del usuario con el programa al modelo tradicional de eventos. JSF es la evolución estándar de Struts, por los mismos que realizaron Struts. Es un estándar claro y potente para poder hacer aplicaciones visuales mas potentes.

Por ejemplo un ciclo de vida propio . la navegación. Nos permite configurar y definir externamente el flujo de pantallas. conversores y eventos y javabeans. validadores. Nos aporta un ciclo de vida claro estándar.` ` ` ` Nos da Renderización. árbol de componentes visuales. Nos permite modificar o incorporar componentes básicos propios en la arquitectura.

Nos permite crear componentes propios para reutilizar.` ` ` ` ` ` ` Aporta tags para funcionar sobre jsps. Se podría usar JSF en otros entornos diferentes a jsp. Tenemos una librería estándar de JSF-Html para crear aplicaciones web. . Retrasa la renderización hasta el último momento para poder renderizar con toda la información bien preparada. JSF tiene un Servlet como entrada de las llamadas a su arquitectura. Nos da un nivel de información independiente de estar en un contenedor web-servlets o un contenedor basado en portlets.

. Se basa en un fichero de configuración. Validadores. Conversores. por defecto faces-config.xml ¿Qué gestionamos en el faces-config? Componentes (Edit/ Label/ ComboBox).. Beans (Java Beans).` ` ` Se necesita configurar un servlet de JSF para enlazar con el contenedor Web. Navegación Aspectos avanzados..

Normalmente de tipo x /facesl* x *.jsf .` Debemos registrar el servlet.faces x *.webapp. javaxfaces.FacesServlet ` Tenemos que hacer el servlet-mapping de las uris que vamos a tratar con JSF.

LIFECYCLE_lD instancia de LifeCycle a usar por JSF por defecto LifecycleFactory.xml.CONFIG_FILES indicando una lista relativa a nuestro contexto donde están los archivos de configuración de JSF.DEFAULT_SUFFIX indica el sufijo por defecto de recursos conteniendo componentes JSF.faces.faces. por defecto .STATE_SAVING_METHOD La localización donde se va a guardar la información de estado: x server o client. jsp.faces. javax.` Se pueden configurar los siguientes parámetros globales (context-param): javax.DEFAULT_LIFECYCLE.faces. javax. x Por defecto server en el HttpSession . javax. Por defecto carga /WEB-lNF/faces-config.

Registrar validadores propios. Registrar Renders.` ` ` La etiqueta principal es <faces-config>. Podemos tener mas de un archivo de configuración. Podemos configurar: Java beans. Configurar reglas de navegación. Registrar componentes propios. . Registrar conversores propios.

. ¿Qué ha ocurrido? .jsf ¿? ` Probamos la aplicación.jsp redirija mediante response.` ` Partimos de piloto 0.) a welcome. entorno de trabajo basado en Maven2 y generado mediante el arquetipo para MyFaces.0.jsp con un mensaje de ³Hola Mundo´ Index.sendRedirect(.. Lo modificamos para que: Aparezca una nueva página welcome.

sun.. .sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java. En JSF todas las vistas deben estar contenidas en un elemento f:view: <%@ taglib uri="http://java..` ` Welcome.com/jsf/core" prefix="f" %> <f:view> . </f:view> ` ¿Por qué? Encapsular la JSF en el componente vista.jsf no es aún una vista válida JSF.

.` ` ` ` Permite declarar los beans que van a ir instanciando automáticamente y en el scope que se van a a encontrar. none. Configurar propiedades de los beans. Scopes: request. Poner el valor de una propiedad de un bean al resultado de la evaluación de un método valuebinding. Session. x El bean es inicializado cada vez que es referenciada y no se guarda en ningún scope. application.

<managed-bean> <managed-bean-name>NA</managed-bean-name> <managed-bean-class>model. «««««««««« </managed-bean-name> </managed-bean> .ImageArea</managed -bean-class> <managed-bean-scope>application</managed-bean-scope> <managed-property> <property-name>shape</property-name> <value>poly</value> </managed-property> ««««««««..

UsuarioBean</managed-beanclass> <managed-property> <property-name>nombre</property-name> <value>invitado</value> </managed-property> </managed-bean> .si.uniovi.si. creamos la clase es.` Vamos a inyectar nuestro primer bean en JSF: En primer lugar.xml como bean usuario.UsuarioBean con una propiedad nombre Lo declaramos en el faces-config. inicializando su propiedad nombre con la cadena ³Invitado´.uniovi. <managed-bean> <managed-bean-name>usuario</managed-bean-name> <managed-bean-class>es.

¿Funciona? Resuelto en piloto 1.<br> Probar a acceder mediante piloto/entrada.nombre}"/>.jsf ¿Funciona? ` Acceder ahora mediante piloto/entrada.jsp ¿Y ahora? ` Quitar ahora f:view y probar con entrada.` Creamos una nueva vista entrada.jsp y. mostramos la propiedad nombre del bean usuario mediante el componente de salida: Hola <h:outputText value="#{usuario. ` .0. dentro. bienvenido a mi sitio web.jsf.

` ` Realiza una acción al ser activado. EL String es usado por el NavigationHandier para determinar la pagina siguiente de acceso. Propiedades básicas: Action String o method-binding al método que devuelve ese String. actionListener para escuchar los eventos de acción .

/> commandLink representa un elemento de acción en formato link (con <a></a>) .` Dos tipos de etiquetas básicas commanButton representa un botón <h:commandButton .. x La etiqueta ha de contener una etiqueta outputText para representar donde el usuario clickea para generar el evento .

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.` ` Representa los campos de entrada. valueChangeListener method-binding para escuchar los cambios de valor . Validatos method-binding a la validación.

tenemos que ceñirnos a sus reglas y utilizar sus etiquetas en lugar de las etiquetas estándar HTML. Éstas implementan más lógica por detrás que nosotros no vemos pero que nos ahorra trabajo.login}"/> <h:commandButton value="Login" action=³¿?"/> </h:form> . Ejemplo de formulario en JSF: <h:form> <h:inputText value="#{usuario.` ` ` Cuando apliquemos JSF.

¿Qué ocurre? Examinamos el código fuente.` Editamos welcome.jsp y añadimos lo siguiente: <h:form> <h:inputText value="#{usuario. ¿Adonde apunta el formulario? ¿Por qué? .jsf"/> </h:form> Accedemos a la aplicación y pulsamos el botón...nombre}"/> <h:commandButton value="Enviar" action=³entrada.

jsf Lo que debemos poner en el campo action de un componente de comando (nótese que no es a nivel de formulario) es la acción que se desea disparar ¿Cómo se navega entonces? Estableciendo el mapa de navegación en el controlador. Entonces. . TODAS las peticiones van a la propia página. ¿Dónde está el truco? El servlet mapping hace que el controlador caputure TODAS las peticiones que concuerden con la extensión *.` ` ` ` En JSF.

x el usuario necesita logearse primero. Salidas típicas: success: x todo ocurrió correctamente. IR a pagina de logon x la búsqueda no encontró nada. La siguiente pagina depende del método action sobre el que se haya pinchado y la salida lógica que de la etiqueta referenciada. Failure: Logon: x hubo algo mal. Ir a la pagina de búsqueda de nuevo No result: . ir a una página de error. Cada regla define como navegar desde una página hacia otro conjunto de páginas.` ` ` ` Permite configurar cual será la siguiente pagina después de pulsar un boton o link.

` ` ` `

From-view-id
Indica la página 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 transición.

To-view-id
indica el id de la vista a la que pasamos

<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>

`

Vamos a establecer una regla de navegación en el faces-config.xml que determine que cuando se dispara la acción login desde la página 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 acción login. ¿Funciona?

y nosotros no hemos establecido ninguno diferente. Volver a probar la aplicación.0 .xml y forzar que el beanscope sea request.` ` ` Problema: El bean aparece siempre con el mismo valor. ¿Por qué?: El scope por defecto de los beans es page. Resuelto en piloto 2. Editar el faces-config.

</managed-bean> Con #{expresion languaje} podemos referirnos a los métodos. propiedades y elementos .defaultAreaCode}</value> </managed-property> «««««.` <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.

75</value> </map-entry> <map-entry> <key>Web Servers for Fun and Profit</key> <value>40. 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-entries> </managed-property> </managed-bean> .` Es un Map de Collections.

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

Alternativa: Navegación dinámica .` ` ` ¿Cómo hacemos que nuestras vistas interactúen con el modelo? Sabemos como forzar a que JSF invoque un método get o set sobre un bean. sería desnaturalizar el método. luego ¿Implementando lógica en los accessors? No.

la redirección dependerá del resultado de la interacción con el modelo. . el botón de commando dispara una acción que. En las aplicaciones reales.` ` En el ejemplo que hemos visto. vuelvo a la página de login y muestro un error. nos redirige de terminantemente a otra vista. tal y como hemos configurado. Ejemplo hago login y: Si es correcto. paso a la página de entrada Si no. ` Para esto necesito: Elementos donde implementar la lógica decide la navegación La posibilidad de establecer las diferentes transiciones en base al resultado.

<h:commandButton label="Login" action="#{loginController.` ` Para implementar navegación dinámica.verifyUser}"/> ` . Ejemplo: En este caso. debemos utilizar en el elemento de comando que hace submit una expresión de método. al pulsar el botón se invocará el método verifyUser del bean dado de alta como loginController.

else return ³login-error".` ` ¿Cómo se determina el destino tras ejecutar un método de bean? Desde el bean: if (.) return "success". .. ` El bean dispara acciones en base a las cuales se determinará cual será la siguiente vista..

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

LoginAction tal que: x Contenga una propiedad de tipo UsuarioBean x Tenga un método login que: x Si usuario=contraseña=admin entonces dispare ³success´ x Si no.` Vamos a implementar e inyectar un bean que se encarge de nuestro futuro proceso de login. Para eso: Añadimos una propiedad password al bean usuario y completamos el formulario de la página welcome para que se recoja la contraseña.xml ¿Funciona? ¿Qué ocurre? . dispare login-error. Creamos es. Establecemos la navegación en el faces-config.uniovi.si.

mybeans.mycompany.mybeans.AddressBean</managed-bean-class> <managed-bean-scope> none </managed-bean-scope> <managed-property> <property-name>street</property-name> <null-value/> <managed-property> </managed-bean> .<managed-bean> <managed-bean-name>customer</managed-bean-name> <managed-bean-class>com .mycompany.CustomerBean</managed-bean-class> <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 .

xml Probar la aplicación.0 .` ` Inyectar el bean usuario en el bean loginAction en el faces-config. Resuelto en piloto 3.

cuente cuantos logins se realizan en la aplicación contando todos los de los usuarios. ¿Desde donde lo hacemos? ¿En qué clase lo inyectamos? Visualizar el resultado del contador en la página final. basándose en el contexto de la aplicación. .` ` ` Modificar la versión anterior para añadir un contador que.

Los elementos de JSF se clasifican en: Componentes JSP Objetos Implícitos . etc. como los formularios. los comandos.` ` Hasta ahora hemos visto y usado algunos de los elementos que nos aporta JSF.

Vamos a ver los componentes base con su reflejo sobre los componentes Html.` ` ` ` ` ` JSF basa sus vistas en un árbol de nodos visuales. Tenemos una implementación de HTML que implementa de diversa manera estos componentes base. Los nodos tienen asociados un renderizador que crea su visualización. Entre llamada y llamada se recrea el árbol de objetos en el lado servidor. . Hay un conjunto estándar de componentes base.

param paramValues requestScope sessionScope view x Indica el UIComponent que es raíz del árbol para esta llamada . Con el Expresion Languaje de JSF tenemos una serie de objetos implícitos en el contenedor web estándar: applicationScope cookie facesContext header headerValues initParam.` ` Podemos usar el EL para asociar métodos y propiedades a los elementos #{.}.. .

El renderizador se encargara de generar su representación visual según convenga. Todo componente visual tiene una representación como objeto en el servidor en una jerarquía nodal. .` ` ` Los componentes han de tener un constructor vacío para poder instanciarse.

El elemento funcional base que hereda de UIComponent es UIComponentBase. Todo componente debe especificar constantes indicando el tipo bajo el cual el componente es registrado y la familia para seleccionar el render adecuado. El elemento raíz de un árbol es UIViewRoot. Component_FAMILY . El elemento base de la jerarquía es UIComponent.facescomponent. COMPONENT_TYPE.` ` ` ` ` ` El paquete visual principal es javax. Todo elemento visual forma parte de un árbol nodal de elementos.

. getViewNode x Nos permite acceder al nodo principal del árbol Buscar componentes hijo. bien impuesto o bien generado.` Propiedades nodales getParent. getChildrenCount. Cada componente tiene un Id. getChildren.

getAttibutes nos permite acceder a las propiedades y atributos del componente . Todo componente pertenece a una familia y un renderType. la conjunción de ambos determina el render a utilizar.` ` ` Nos permite acceder al FacesContext al que pertenece el componente. Casi cada componente UI va a tener una etiqueta asociada.

` ` ` Al crear componentes tenemos que implementar la codificación y decodificación de la información. Decode: Leemos el dato del request y propagamos su valor. En caso de no necesitar tener en cuenta los componentes hijo solo implementaremos en encodeEnd. . Encode: EncodeBegin EncodeChildren EncodeEnd Durante la fase de renderización los datos se pasan al lenguaje de marcado.

Tiene asociado un RenderKit: Es una familia de renders.` ` ` ` Es el nodo raíz de un árbol de componentes visuales. Nos permite poner el locale del árbol. Su etiqueta es f:view y su único atributo opcional es locale . Hereda de UIBaseComponent. Cada render en el RenderKit esta designado por tipo y familia que renderiza.

com/jsf/html prefix=´h´ %> .com/jsf/core prefix=´f´ %> <%@ taglib uri= uri=http://java.sun.` Actualmente hay dos librerías de etiquetas básicas: <%@ taglib uri=http://java.sun.

Con el render de H L podemos ver ue el Componente IData tiene una implementaron (por extensi n) H LDataTable que contiene los atributos confi urables relativos a Html específicos del Render </f:subview> ..` ` Los omponentes n e est r meti os entro el n ni o nodo r i f: i > Cuando se reali a un jsp:import> o :include> todos elementos incorporadas an de meterse en un f: subview> <f:subview> x <c:include .> ` ` Cual uier texto de plantilla incluido por el include o el import. actualmente debe meterse dentro de una eti ueta <f: verbatim> Cada elemento va a tener los atributos del componente mas los añadidos por el render..

.(UI. l edi te: si esta a true indica que los eventos. Val e indica el valor del componente. Binding identifica una propiedad de un bean y asocia la instancia I del componente a esa propiedad (set.. como literal o enlazado con una propiedad del modelo de informaci n. st leClass especifica el class del CSS (cascading st le sheet). si no se lo ponemos es enerado automáticamente. )). validaciones conversiones se reali an en la fase de appl request en vez de en una fase posterior.. St le especifica el cascading st le sheet para la etiqueta.propiedad} .` Propiedades usuales: Id del ente. Todos los atri tos excepto id ar per iten la asociaci n de al e. x #{objeto. Rendered indica si el componente a de ser renderizado.inding con el xpresion Lenguaje de Java Server Faces.

. <h:form>.</h:form> .. Engloba a todos los componentes que muestran o recogen información.` ` Representa un form de entrada.

El atributo var indica la variable sobre la que se va a ir guardando el objeto de datos en cada iteración.. <h:dataTable.` ` ` ` ` ` Representa una tabla de información.>. Tiene UIColumns dentro. El atributo value indica la colección sobre la que iterar. Soporta estar enlazado con una colección de objetos sobre la que itera.. ..

Javaxfaces.RowSet. javax.servlet.ResultSet y javax. .sql.sql.DataModel ` Todos los tipos de datos soportados tienen un Wrapper a DataModel.sql.model.jstl. Un javax.` Tipos de datos soportados: Listas y arrays de beans. la implementación encapsula nuestro objeto en el wrapper correspondiente. Una sóla bean.jsp.ResultSet.

Rows indica el número de filas a mostrar. Existen varias propiedades que pueden indicar listas de estilos para los diferentes elementos: columnClasses footerClass headerClass rowClass StyleClass .` ` ` First indica la primera fila a ser mostrada.

` <h:column> . no en cada bucle. Un facet se usa para representar un componente que es independiente de la relación padre-hijo en el árbol de elementos.` ` Representa una columna de información en un UIData Cada columna puede tener uno o varios facet que indicarían 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. En el caso de las columnas las cabeceras y pies sólo se pintan una vez.

autor}"/> . </h:dataTable> .libros}" var="libro"> <h:column> <f:facet name="header"> <h:outputText value="Título" /> </f:facet> <h:outputText value="#{libro.<h:dataTable value="#{gestionLibrosService.titulo}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Autor" /> </f:facet> <h:outputText value="#{libro...

jsp para que muestre el catálogo de la librería usando un tag h:dataTable. título.0 del piloto y: Crear una clase LibroBean con las propiedades autor. descripción y precio. ¿Qué scope tendrán que tener los libros? ¿Y la librería? Resuelto en piloto 4. Crear una clase Libreria que contenga un Vector de LibroBeans almacenados en una propiedad catalogo Declarar una librería con al menos 3 libros diferentes y denominarla liberia Modificar la página entrada.0 .` Modificar la versión 3.

Una petición con JSF genera una respuesta sin 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 petición sin JSF genera una respuesta con JSF. ` A su vez la aplicación también puede recibir peticiones sin JSF que generen respuestas sin JSF . Una petición con JSF genera un respuesta con JSF.

Contiene toda la información relativa al estado en la request y la renderización de la respuesta. . No se le debe referenciar por un objeto que tenga una vida mas larga que la request .` ` ` ` ` Toda llamada o request tiene asociado un FaceContext y al hilo de llamada. Encapsula el elemento raíz visual ViewRoot. El FaceContext solo debe existir durante la request hasta que se llame a su método release.

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 información que tendríamos como servlet. Nos permite acceder al Singleton de Application. Como flujos de escritura para los renderizadores. Encapsula ResponseWriter -salida de cáracteres. .y ResponseStream ²salida binaria-.` ` ` ` Encapsula los posibles mensajes.

.

.

No se realizan mas acciones. ` Se crea el viewID de la URI y de los valores de prefijo: ViewHandler. Examina si FacesContext tiene un UIViewRoot en caso de tenerlo: Le asigna el locale correspondiente (internacionalización). 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ó.` ` El servidor recibe una llamada y recompone los objetos de la vista en el servidor.DEFAULT_SUFFIX_NAME .

renderResponse() Si la petición no contiene parámetros de llamada ni datos en POST se llama a renderResponse .createView() y a FacesContext .` 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 había vista asociada por lo que se crea una y se pasa al renderResponse: x se llama a ViewHandler.

` ` ` 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 había y si acaso se ha creado uno nuevo.

.

Estos eventos son notificados al final de esta fase . Se llama al método processDecodes() de todos los componentes del árbol UIViewRoot.` ` ` Da la oportunidad a los componentes a actualizar sus valores a los valores que llegan de la request. Los componentes que implementan ActionSource que reconocen que fueron activados encolan su evento.

` Los componentes que implementan EditableValueHolder que tienen la propiedad immediate a true realizan la conversión y validación. lncluyendo el potencial lanzamiento del evento ValueChange. Normalmente immediate esta a false esto ocurre posteriormente en la fase de Process Validations .

.

En cualquier momento si nuestra lógica en los decode. En caso contrario pasamos a la fase de Process Validations . y el componente que la lanza será marcado como invalido. 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.` ` ` ` Todo error producirá un mensaje que se encolara en el FaceContext. o en los eventos llama a responseComplete en FacesContext.

.

` En cualquier validador puede llamar a responseComplete o a renderResponse de FacesContext. . Y la propiedad valid del componente se pone a false.` ` Se procesan las validaciones llamando a processValidators. Cualquier fallo en la validación mete un mensaje de error en el FacesContext.

.

La actualización dentro de un componente se realiza llamando al método updateModel. Es el momento de actualizar los datos del modelo de la aplicación.processUpdates.` ` ` ` ` Llegados a esta fase se asume que los contenidos son sintácticamente y semánticamente correctos. Se asume que el valor local de los componentes ha sido actualizado. Esto se produce recursivamente llamando a UlComponent. .

. Cualquiera de nuestros métodos podría llamar a responseComplete o a renderResponse. Al finalizar esta fase los valores del modelo de datos han sido actualizados y los valores de los componentes han sido vaciados.` ` ` Durante la actualización los eventos son encolados hasta la finalización de la fase donde se procesan.

.

Se llama a todos los eventos encolados con phaseId. Excepcionalmente se podría llegar a cambiar el actionListener por defecto con setActionListener . Se llama al método processApplication de UIViewRoot.` ` ` ` Si se alcanza esta fase se asume que la actualización del modelo ha sido completada.INVOKE_APPLICATION.

.

Hace que el estado de la respuesta sea guardado para ser procesado en llamadas sucesivas.` ` ` ` ` Hace que la respuesta sea renderizada al cliente. Para los elementos que implementan ValueHolder se ha de producir su conversión. Esta información ha de estar disponible para que Restore View pueda acceder a ella en sucesivas llamadas. . Antes de completarse el estado de la vista ha de ser guardado usando los métodos de la clase StateManager. Cuando un componente de árbol es seleccionado para renderizarse se llama a su método de encodexxx().

nos puede interesar procesar juntos. sino a agrupaciones que datos que por motivos prácticos. Es imprescindible para validaciones en las que se han de comprobar relaciones entre componentes. Ejemplo: Representación de formularios .` ` ` Son beans que no responden a entidades. a nivel no de valores sino de componentes.

sino su referencia...oldUser}"/> Lo que le pasa JSF al formulario al hacer binding no es el valor del componente. . } . //getters and setters.. En la JSP: <h:outputText binding="#{changeSessionForm. UIOutput oldUser. por ejemplo: Public class ChangeSessionForm { UIInput newUser.` Si queremos hacer un backing bean para un formulario de cambio de usuario en sesión que muestra y recibe información al mismo tiempo..

si.0 . Resuelto en piloto 5.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.uniovi.` Vamos a alterar el proceso de login para utilizar es.backing.

Ej: New SelectItem(³010´.` ` ` Los elementos de formulario que muestran elementos entre los que seleccionar (combo. ` ¿Cómo se conecta con el formulario? . radio.´The Matrix´). etc) comparten modo de funcionamiento. listas. La entrada de datos debe ser una colección de elementos SelectItem.

` ` Etiqueta h:selectBooleanCheckbox Representa un estado booleano .

x Layout indica como se han de poner los checkbox pageDirection/lineDirection.` Tres renderizaciones básicas selectManycheckbox x Muestra una lista de checkboxes x Value indica el set de elementos seleccionados actualmente. selectManyListBox selectManyMenu . x Contiene etiquetas selectItem o selectItems representando a los elementos.

` Permite seleccionar solo un elemento: selectOneRadio selectOneMenu selectOneListbox ` Su contenido son colecciones de Selectltem o Selectltems .

` ` ` `

Nos permiten anidar elementos en los select f:SelectItem Un UISelectItems representa a una colección 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.

`

Ej: para cargar un combo...
Bean pruebaForm:

Private UIInput propiedadDestino; public Collection getOpciones() { opciones = new ArrayList(); opciones SelectItem(³01´,³Opción 1")); opciones SelectItem(³02",³Opción 2")); return opciones; }

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

`

Vamos a añadir al formulario de login un combo con el idioma preferido por el usuario. Para ello:
Añadimos una propiedad idioma de tipo IUInput al LoginForm, y un método getIdiomas que retorne una colección de SelectItems con:
x ³es´,´Español´ x ³en´,´English´

Lo enlazamos y mostramos lo recibido en el LoginForm al pulsar el botón. (Resuelto en piloto 6.0)

0 para: Añadir un formulario en entrada. Tendrá que tener un método public List<Entry> getProductos() que retorne una lista de objetos entry obtenidos mediante el método entrySet de la HashMap.` Completar piloto 6. .jsp con: x Un combo donde se muestre la lista de libros x Un editBox donde se introduzca la cantidad del libro seleccionado Un backing bean CarritoForm con un método add para gestionar el carrito de la compra Un CarritoBean que resida en sesión y que encapsule una HashMap.

con un enlace a la página anterior: <h:form> <h:commandLink action="success">Volver</h:commandLink> </h:form> Resuelto en piloto 7.Una página vercarrito que muestre el estado del carrito de la compra mediante una tabla.0 .

En cualquier aplicación es conveniente evitar tener las cadenas de texto hardcodeadas en el código fuente de las pantallas o páginas. Los resource bundles sirven para seleccionar el mensaje de error en función de la clave.welcome}"/> El fichero messages. buscándolo en los resource bundle cargados.properties: welcome=Benvenido a mi página web!!!! . Ejemplo: <h:outputText value="#{msgs. En el faces-config: <application> <resource-bundle> <base-name>messages</base-name> <var>msgs</var> </resource-bundle> </application> Luego los referenciamos mediante EL.

. welcome.jsp.properties.0 . Creamos messages. Extraer los mensajes de al menos una de las vistas. Probar la aplicación.0. Resuelto en piloto 8. Lo configuramos como fichero de recursos con el prefijo msgs.` ` ` ` ` Sobre piloto 7. por ejemplo..

etc).properties Messages_fr. Para internacionalizar la aplicación: un fichero de recursos por locale: messages. .properties .fr.properties Messages_en... El locale responde a un código estandarizado (es.` ` ` ` JSF aprovecha la externalización de cadenas de texto para implementar la internacionalización de etiquetas. representado por el parámetro LOCALE.en. En la request viaja el idioma preferido del navegador.

properties. Traducimos las cadenas de texto al inglés Para probarlo. . Para ello: Creamos un fichero messages_en.properties copiando el messages.` Internacionalizar la aplicación para el inglés. establecemos en el navegador el inglés como idioma por defecto.

` ` Actualmente se recomienda que el usuario pueda seleccionar explícitamente el idioma por encima de lo que diga el parámetro de idioma preferido del navegador. JSF permite establecer el locale de varias formas diferentes: .

Estableciéndolo directamente en el facesconfig.1. 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> .xml.

2.getCurrentInstance(). viewRoot. . Establecerlo por programa UIViewRoot object: UIViewRoot viewRoot = FacesContext. podemos establecerlo dinámicamente <f:view locale="#{user.locale}"/> 3. Establecerlo como parámetro de la etiqueta f:view: <f:view locale="de"> Ventaja.setLocale(new Locale("de")).getViewRoot().

internacionalizar alguna de las páginas posteriores al proceso de login. ¿Dónde recogemos el locale? Resuelto en piloto 9.` ` ` Modificar la aplicación para que el criterio del idioma que estamos seleccionando al hacer login cambie el locale de la aplicación. Para verlo reflejado.0 .

component. Converter es el interfaz capaz de hacer transformaciones string-objeto y objeto-string.FacesContext context.Iang.faces.lang.context.context. Su atributo converteride indica el id del conversor a usar. También se puede anidar dentro de una etiqueta con f:converter.Object value) ` ` ` Podemos asociar un conversor a un lnput/Output. . public java. FacesContext context.faces. javax. UlComponent component. javax.com ponent. UlComponent component.langObject getAsObject(javax. El atributo converter indica la clase java que implementa ese interface.faces. java.String getAsString(javax.faces.lang.String value) public java.` ` JSF aporta una colección de conversores predefinidos para tipos de datos estádar. java.

` Tenemos conversores automáticos para los tipos básicos: BigDecimalConverter BigIntegerConverter ByteConverter CharacterConverter DateTimeConverter DoubleConverter FloatConverter IntegerConverter LongConverter NumberConverter ShortConverter .

locale: indica el Locale. long y full. por defecto FacesContext.` f:dateTimeConverter permite hacer conversiones de fecha: datestyle: indica el formato: default.getLocale. pattern: indica el patrón de fecha (dd/MM/yy por ejemplo) timeStyle: define el formato de hora timeZone: type: indica si el string va a contener una fecha. short. hora o ambos . medium.

moneda o porcentaje . minFractionDigits.` F:numberConverter permite controlar conversiones de numero currencyCode. maxFractionDigits. maxIntegerDigits. integerOnly: boolean indica si se va a parsear la parte entera del valor. Type: indica si el valor a parsear y formatear es número. pattern. currencySymbol. minIntegerDigits. locale. groupingUsed: boolean indica si la cadena de salida tiene separadores de agrupamiento.

` El funcionamiento cuando hay un conversor es el siguiente: El usuario envía los datos Se vuelvan al árbol de componentes Se invocan los conversores En caso de error. . se muestran los errores. en caso de que exista una etiqueta h:messages. x Se añaden los mensajes de error a la lista global de mensajes x Se vuelve a mostrar la página original y.

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

unidades}"> <f:convertNumber integerOnly="true"/> </h:inputText> <h:message for=³unidades"/> .¿Cómo muestro los errores de conversión/validación? Si quiero mostrarlos todos juntos: ` <h:messages/> Si quiero mostrar los específicos de un campo: <h:inputText id=³unidades" label=³Unidades" binding="#{bean.

¿Funciona? ¿Cómo sale el mensaje? Resuelto en piloto 10.0. Probarlo metiendo caracteres en el campo. .` ` Basarse en el ejemplo anterior para aplicar un conversor para la cantidad de productos que se añaden al carrito y mostrar los errores asociados al cambo justo debajo del mismo.

Ejemplo: . para internacionalizar la aplicación Para ello. entre otras cosas.` ` ` Lo habitual será personalizar los mensajes de error que disparan los validadores. en los message-bundles sobrescribimos los mensajes predefinidos haciendo referencia a los códigos de identificación de cada mensaje.

converter.converter.converter.9E-324 and 1.DoubleC {2}: "{0}" must be a number onverter.DOUBLE_detail between 4.faces. javax. javax. Any value other than 'true' will evaluate to . INTEGER consisting of one or more digits.converter.INTEGER_detail between -2147483648 and 2147483647.Integer {2}: "{0}" must be a number Converter.7976931348623157E308.Boolean {1}: "{0}" must be 'true' or Converter.faces.DOUBLE consisting of one or more digits.Integer {2}: "{0}" must be a number Converter.faces.DoubleC {2}: "{0}" must be a number onverter.BOOLEAN_detail 'false'.faces.converter.Exampl e: {1} javax.Código mensaje javax. Example: {1} javax.faces.

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

. Mira que este entre dos valores dados. minimum-maximum. x Mira que la longitud de la cadena este entre un mínimo y un máximo La clase LongRangeValidator con tag f:validateLongRange x Para valores que se puedan convertir a long. ` ` La clase LengthValidator con tag f:validateLength.` La clase DoubleRangeValidator con tag f:validateDoubleRange: Valida un valor que puede ser convertido a coma flotante. x Mira que este entre dos valores dados.

` Parámetros: .

campoRequerido}"> <f:validateLength minimum="13"/> </h:inputText> Taller práctico Modificar el piloto anterior para que además se requiera el campo cantidad. basta con establecer el atributo required a true.` Para comprobar que un dato está presente. <h:inputText id="card" value="#{payment. no hace falta ningún validador anidado. .card}" required="true´requiredMessage="#{msgs.

jsp para que: Los campos login y password sean obligatorios.0 .` Modificar la welcome. ` Resuelto en piloto11. La password tenga al menos 3 caracteres Se visualicen mensajes personalizados e internacionalizados.

Enlazar desde welcome. Crear una página registro.jsp con: <h:outputLink value="registro.jsp a registro.jsp y un backingbean RegistroForm con un método registro que reciba login y password y añada el nuevo usuario al bean usuarios.jsf"> <f:verbatim>Nuevo usuario</f:verbatim> </h:outputLink> Resuelto en piloto 12.0 . Modificar el proceso de login para que el proceso se realice contra los usuarios del bean Usuarios.` 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 aplicación.

En Web.` ` ` 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.NET simula esto encapsulando el evento en una request que es enviada al servidor sin llegar a disparar la acción del formulario. ¿Se puede hacer esto? JSF... al igual que otras plataformas como . . dado que trabajamos sobre Http.

Action events x Los disparan los elementos UICommand cuando el botón o enlace asociado es activado.` JSF soporta tres tipos de eventos: Value change events x Disparados por elementos UIInput cuando el valor que contienen cambia. Phase Events x Son disparados rutinariamente por el ciclo de vida JSF. .

Ej: Combo de paises + combo provincias. public void countryChanged(ValueChangeEvent event) { FacesContext context = FacesContext. <h:selectOneMenu value="#{form.getNewValue())).getCurrentInstance(). context.setLocale(new Locale( (String) event. } .countryChanged}"> <f:selectItems value="#{form..country}" onchange="submit()" valueChangeListener="#{form.` Pensados para elementos dependientes en los formularios.getViewRoot()..countryNames que se espera recibir un evento.countryNames}"/> </h:selectOneMenu> ` Esto dispara el método form.

Método UIComponent getComponent() Object getNewValue() Object getOldValue() Los heredados de FacesEvent... void queue() PhaseId getPhaseId() void setPhaseId(PhaseId)

Descripción Retorna una referencia al objeto que disparó el evento. Retorna el nuevo valor Retorna el valor antiguo Encola el evento para que sea disparado al final del ciclo de vida actual Devuelve el id de la fase en la que nos encontramos. Marca el evento con el identificador de la fase en la que fue añadido a la cola.

`

Modificar el piloto para que el combo del idioma que se muestra en la página welcome tenga asociado un manejador de evento idiomaCambiado en loginForm de forma que cambie el idioma de la aplicación. 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

`

`

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 método 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

¿En qué se diferencian de los actions? .linkActivated}"> . el formulario se envía y el controlador dispara los eventos. Entonces... </h:commandLink> ` ` Cuando se activa el componente..` ` Son disparados por los objetos UICommand cuando se activa el componente Se invocan durante la fase Invoke Application <h:commandLink actionListener="#{bean..

No pueden decidir qué mensaje se envía al controlador. . generará una redirección u otra. Deciden sobre la navegabilidad del sistema ` Action listeners: Orientados a ejecutar lógica de presentación. ` ` Los dos tipos de elementos trabajan coordinadamente cuando el Action requiere información del interfaz de usuario.` Actions: Diseñados para la lógica de negocio. Ejemplo: Una imagen enlazada que dependiendo de la zona pulsada.

intValue().intValue()..getRequestParameterMap().40.getClientId(context).act}"/> En el backing bean. String clientId = e. public String act() { return outcome.45.get(clientId + ".contains(new Point(x.40. } .. if (washingtonRect.listen}" action="#{rushmore.get(clientId + "..` Enlace en la JSP: <h:commandButton image="mountrushmore. int x = new Integer((String) requestParams. private Rectangle jeffersonRect = new Rectangle(115.40).jpg" actionListener="#{rushmore.x")). int y = new Integer((String) requestParams.y")). Map requestParams = context.getComponent().40). private String outcome.y))) outcome = "washington". private Rectangle washingtonRect = new Rectangle(70.getCurrentInstance(). public void listen(ActionEvent e) { FacesContext context = FacesContext. . outcome = null..getExternalContext().30.

Lo asociamos al botón de submit del formulario de la página entrada. ¿Cuál se dispara primero? . creamos un nuevo método public void listen(ActionEvent e) en el CarritoForm que muestre un mensaje por pantalla demostrando que ha sido invocado.jsp.` ` En primer lugar.

` Extender la versión anterior para: Desligar al botón de submit del listener Crear un enlace activo (h:commandLink) que: x no tenga atributo action x Esté asociado al listener que hemos creado x Se represente con la cadena de texto Incrementa Modificar el método listen para que cada vez que se ejecuta. además de mostrar el mensaje: x Tome el string del UIInput cantidad x Cree un entero y le sume uno x Estableza de nuevo el valor calculado en el componente cantidad.0 . Resuelto en piloto 15.

.` ` 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.

country}" onchange="submit()"> <f:valueChangeListener type="com.countryChanged}"> <f:selectItems value="#{form.country}" onchange="submit()" valueChangeListener="#{form.CountryListener"/> <f:selectItems value="#{form.countryNames}"/> </h:selectOneMenu> Versión con f:valueChangeListener: <h:selectOneMenu value="#{form.` Diferencias en la aplicación: Versión con el atributo <h:selectOneMenu value="#{form.corejsf.countryNames}"/> </h:selectOneMenu> No es una method expression sino una clase! .

} } ` El controlador invoca el método processValueChange tras cada cambio. ..` 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) { ..

.` Similar a la anterior: Y la clase. implementando la interfaz ActionListener: <f:actionListener type=" com. } } .. RushmoreListener "/> ` public class RushmoreListener implements ActionListener { public void processAction(ValueChangeEvent event) { .corejsf.

Asociarla a la etiqueta del combo de la págin entrada.jsp. son dos alternativas incompatibles! Resuelto en piloto 16.` ` ` Crear una clase LibroCambiadoListener que implemente la interfaz ValueChangeListener Implementar su método processValueChange para que saque un mensaje.0 . Ojo! Hay que quitar el atributo que la liga al otro listener.

` Problema: En casos como el combo de cambio de idioma. se nos están disparando los validadores que conviven dentro del mismo formulario. ¿Porqué? Se disparan los validadores y conversores Se procesan los eventos .

idioma}" onchange="submit()´ valueChangeListener="#{loginAction.` Si marcamos un componente como inmediato: <h:selectOneMenu binding="#{loginForm.idiomaCambiado}" immediate="true"> .

` Problema: El ciclo de vida sigue si rumbo normal tras la validación y procesado de eventos de los componentes inmediatos ` Solución: Cortamos el flujo desde el listener y forzamos la renderización de la respuesta (el atajo en el gráfico anterior) context. pero no hacer falta forzar el renderizado porque al terminar van directos a dicha fase. Taller práctico ` Hacerlo sobre la versión actual del piloto para el cambio de idioma en el login ¿Comandos inmediatos? ` En el caso de los comandos. .renderResponse(). también podemos hacerlos inmediatos.

getCurrentInstance().setLocale(Locale.setLocale(Locale. context.` Supongamos que queremos hacer la internacionalización con dos banderas. return null.gif"/> <h:commandLink action="#{localeChanger.ENGLISH). } public class ChangeLocaleBean { } .getViewRoot().getViewRoot().getCurrentInstance(). context.GERMAN). return null. } public String englishAction() { FacesContext context = FacesContext.englishAction}" immediate="true"> </h:commandLink> ` En el servidor: public String germanAction() { FacesContext context = FacesContext. una por idioma. haciendo que ambas sean commandLinks: <h:graphicImage value="/british_flag.

` Solución: Envío de información desde la interfaz al usuario. Métodos: x f:param x f:setPropertyActionListener x f:attribute .` Problema: Estamos definiendo métodos que son prácticamente iguales ±repetimos lógica.y que en orientación a objetos podría ser uno solo parametrizado.

Si lo usamos en un UICommand. los distintos parámetros se usan para rellenar las variables ({0} is bigger than{1}) que se encuentren en el valor del componente. . los parámetros se añaden como un parámetro de la request.` ` Nos permite adjuntarle un parámetro a un componente. Se comporta diferentemente dependiendo del tipo de componente: Si lo usamos en un h:outputText.

getViewRoot().gif" style="border: 0px"/> <h:commandLink immediate="true´ action="#{localeChanger.getCurrentInstance(). context.String> params=context. } .getExternalContext().getRequestParameterMap(). return params.changeLocale}"> </h:commandLink> ` En el servidor: FacesContext context = FacesContext.get("languageCode"). String languageCode = getLanguageCode(context).` Para el ejemplo anterior: <f:param name="languageCode" value="de"/> <h:graphicImage value="/german_flag. return null. public String changeLocale() { } private String getLanguageCode(FacesContext context) { Map<String.setLocale(new Locale(languageCode)).

a la entrada.` ` Crear en LoginForm un nuevo método idiomaCambiado() que recupere el parámetro nuevoIdioma de la request y establezca el nuevo Locale Añadir dos etiquetas de comando.0 . una por idioma. estableciendo como atributo action (no actionListener!) e inmediato = true.jsp. Resuelto en trabajo 17.

getViewRoot(). Object> attrs = component. por lo que tenemos que usar action listeners (reciben el componente en el evento!) <f:attribute name="languageCode" value="de"/> <h:graphicImage value="/german_flag.getAttributes().get("languageCode").changeLocale}"> </h:commandLink> ` En el servidor UIComponent component = event.` Similar.getComponent(). pero en lugar de añadirlo a la request.gif" style="border: 0px"/> <h:commandLink immediate="true´ actionListener="#{localeChanger. se añade como atributo al componente.setLocale(new Locale(languageCode)). public void changeLocale(ActionEvent event) { } private String getLanguageCode(UIComponent component) { Map<String. String languageCode = getLanguageCode(component). return (String) attrs. FacesContext.getCurrentInstance(). } .

.setLocale(new Locale(languageCode)).getCurrentInstance(). } public void setLanguageCode(String newValue) { languageCode = newValue. establece una propiedad directamente en nuestro backing bean.getViewRoot().changeLocale}"> </h:commandLink> ` En el servidor.. context. <f:setPropertyActionListener target="#{localeChanger.. return null.` Desde JSF 1.2. private String languageCode.languageCode}´ value="de"/> <h:graphicImage value="/german_flag.gif" style="border: 0px"/> <h:commandLink immediate="true´ action="#{localeChanger.. public String changeLocale() { FacesContext context = FacesContext. } public class ChangeLocaleBean { } .

.

<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 </converterclass> </converter> .

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

lang.String</property-class> </property> <component-extension> <component-family>Area</component-family> <renderer-type>DemoArea</renderer-type> </component-extension> </component> ` .lang.String</property-class> </property> <property> <property-name>coords</property-.lang.name> <property-class>java.String</property-class> </property> <property> <property-name>shape</property-name> <property-class>java.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.

alt (texto alternativo. <h:graphiclmage«.` ` ` Muestra una imagen. normalmente mostrado al pasar el ratón por encima) y demás relativas al uso común en html (en la renderización típica Html). Propiedades de un./> .

` ` Indica un dato de salida Con el Renderizador de Html tenemos outputLabel x Su atributo µfor¶ apunta a un id de un campo de entrada con el que se encuentra asociada la etiqueta outputLink x Necesita una etiqueta verbatim que muestra el texto que el usuario clickea para lanzar el link .

x Tiene etiquetas de tipo <f:param value.outputFormat que muestra un mensaje x Permite la utilización de java.. outputText que muestra un texto de una línea .> para indicar los parámetros del mensaje.MessageFormat. x Value indica la frase a parametrizar normalmente de un ResourceBoundle.text..

Sign up to vote on this title
UsefulNot useful