JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
JavaServer Faces
•Sesión 3: Ciclo de vida JSF
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
• Componentes JSF• El ciclo de vida de una petición• Conversores• Validadores• Peticiones JSF• Eventos en JSF
Índice
2
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componentes JSF
• 2 tipos de componentes: etiquetas core (<f:>) y etiquetas HTML (<h:>)
• JavaDoc de las etiquetas: http://java.sun.com/javaee/javaserverfaces/1.2/docs/tlddocs/
• 20 etiquetas <f:> y 25 etiquetas <h:>
• Consultar el Geary & Hortsman
3
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componente <h:dataTable>
• El componente <h:dataTable> genera una tabla HTML a partir de un array o una lista
4
<h:dataTable value="#{selecCursosBB.cursos}" var="curso"> <h:column> <h:outputText value="#{curso.nombre}" /> </h:column> <h:column> <h:outputText value="#{curso.profesor}"/> </h:column> <h:column> <h:outputText value="#{curso.creditos}"/> </h:column></h:dataTable>
Columnas
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Cabeceras de la tabla
• La cabecera se define con la etiqueta <f:facet name=”header”>
5
<h:dataTable value="#{selecCursosBB.cursos}" var="curso"> <h:column> <f:facet name="header"> <h:outputText value="Curso"/> </f:facet> <h:outputText value="#{curso.nombre}" /> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Profesor"/> </f:facet> <h:outputText value="#{curso.profesor}"/> </h:column> ...
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Tablas y CSS
Los atributos como headerClass, columnClasses y rowClasses, sirven para generar tipos CSS que permite diseñar el estilo de las tablas
6
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Apuntes
7
<h:selectManyCheckBox id="hobbitList" value="#{fellowshipOfTheRing.hobbits}"> <f:selectItems value="#{hobbiton.hobbitList}"
var="n" itemValue="#{n}" itemLabel="#{n.bio}" itemDescription="#{n.description}"/>
</h:selectManyCheckBox>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componentes core• Etiquetas con el prefijo <f:>• No definen componentes visuales, sino acciones
asociadas a los componentes• Se ejecutan el servidor, cuando se ha creado el árbol
de componentes
8
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
<f:selectItem>
• Añade ítems de selección hijos a un componente de selección múltiple
9
<h:selectManyCheckbox value="#{selecCursosBean.cursoIds}"> <f:selectItem itemValue="JSP" itemLabel="Servlets y JSP" /> <f:selectItem itemValue="Struts" itemLabel="Struts" /> <f:selectItem itemValue="JSF" itemLabel="JSF" /> <f:selectItem itemValue="JPA" itemLabel="JPA" /></h:selectManyCheckbox>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Paso de parámetros (página JSF)• Las acciones de los beans no pueden tener parámetros• Es posible simular el paso de parámetros de la página al bean con
la etiqueta <f:setPropertyActionListener>• Se llama al método set de la propiedad indicada en la etiqueta con
el valor resultante de la expresión EL
10
<h:form> <h:commandLink value="Click here" action="#{myBean.action}"> <f:setPropertyActionListener target="#{myBean.propertyName1}" value="propertyValue1" /> <f:setPropertyActionListener target="#{myBean.propertyName2}" value="propertyValue2" /> </h:commandLink>
<h:commandButton value="Press here" action="#{myBean.action}"> <f:setPropertyActionListener target="#{myBean.propertyName1}" value="propertyValue1" /> <f:setPropertyActionListener target="#{myBean.propertyName2}" value="propertyValue2" /> </h:commandButton></h:form>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Paso de parámetros (bean gestionado)
11
public class MyBean {
private String propertyName1; private String propertyName2;
// Actions
public void action() { System.out.println("propertyName1: " + propertyName1); System.out.println("propertyName2: " + propertyName2); }
// Setters
public void setPropertyName1(String propertyName1) { this.propertyName1 = propertyName1; }
public void setPropertyName2(String propertyName2) { this.propertyName2 = propertyName2; }}
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
El ciclo de vida visto desde fuera
12
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
El ciclo de vida visto desde dentro
13
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Programa ejemplo: calculadora
14
Componentes que se hacen visibles y se ocultan
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Código de la vista
<f:view> <h:form id="calcForm"> <h:panelGrid columns="3"> <h:outputLabel value="Primer número"/> <h:inputText id="firstNumber" " value="#{calcBean.firstNumber}" " required="true"/> <h:message for="firstNumber"/> ... <h:commandButton value="Calcular" action="#{calculatorController.doOperation}"/> <h:outputText value="Resultado: #{calculatorBB.result}"/><br/> <p></p> <h:commandLink rendered="#{calculatorController.newOperationCommandRendered}" action="#{calculatorController.doNewOperation}" value="Cambiar operación"/> ... </h:form> </f:view>
15
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componentes (1)
16
<h:form id="calcForm"> <h:panelGrid columns="3"> <h:outputLabel value="Primer número"/> <h:inputText id="firstNumber" " value="#{calcBean.firstNumber}" " required="true"/> <h:message for="firstNumber"/> ... <h:commandButton value="Calcular" action="#{calculatorController.doOperation}"/> <h:outputText value="Resultado: #{calculatorBB.result}"/><br/> <p></p> <h:commandLink rendered="#{calculatorController.newOperationCommandRendered}" action="#{calculatorController.doNewOperation}" value="Cambiar operación"/> ...</h:form>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componentes (2)
17
<h:form rendered="#{calculatorController.selectOperationFormRendered}"> <h:selectOneListbox id="operation" required="true" "" value="#{calculatorBB.operation}"> <f:selectItem itemValue="+" itemLabel="suma"/> <f:selectItem itemValue="-" itemLabel="resta"/> <f:selectItem itemValue="*" itemLabel="multiplicación"/> <f:selectItem itemValue="/" itemLabel="división"/> </h:selectOneListbox><br/> <h:commandButton action="#{calculatorController.doSelectOperation}" value="Selecciona operación"/></h:form>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Renderizado de los componentes
18
<f:view> <h:form id="calcForm"> ... <h:commandLink rendered="#{calculatorController.newOperationCommandRendered}" action="#{calculatorController.doNewOperation}" value="Cambiar operación"/> ... </h:form> <h:form rendered="#{calculatorController.selectOperationFormRendered}"> <h:commandButton action="#{calculatorController.doSelectOperation}" value="Selecciona operación"/> </h:form> </f:view>
• Se define con las propiedades booleanas newOperationRendered y selectOperationFormRendered en el bean calculatorController
• Las acciones modifican el valor booleano de esas propieades
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
¿Cuándo se crea el árbol de componentes?
• En la primera petición (http://localhost:8080/calculator) se crea el árbol de componentes a partir del fichero calculator.jsp
• El árbol de componentes (vista) se guarda en el servidor.
• En la segunda petición (cuando el usuario pincha en el enlace “calcular” y se envía el formulario al servidor) JSF obtiene el árbol creado anteriormente, lo guarda en la petición y le aplica el ciclo de vida a la petición.
19
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Controlador (1)
public class CalculatorController { private CalculatorBB numbers; private CalculatorBO calculator = new CalculatorBO(); private boolean selectOperationFormRendered=false; private boolean newOperationCommandRendered=true;
... // getters y setters
public String doNewOperation() { selectOperationFormRendered=true; newOperationCommandRendered=false; return null; } public String doSelectOperation() { selectOperationFormRendered=false; newOperationCommandRendered=true; doOperation(); return null; } ...
20
Propiedades
Mostrandoy ocultando
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Controlador (2)
21
...public String doOperation() { String operation = numbers.getOperation(); int firstNumber = numbers.getFirstNumber(); int secondNumber = numbers.getSecondNumber(); int result = 0; String resultStr = "OK";
if (operation.equals("+")) result = calculator.add(firstNumber, secondNumber); else if (operation.equals("-")) result = calculator.substract(firstNumber, secondNumber); else if (operation.equals("*")) result = calculator.multiply(firstNumber, secondNumber); else if (operation.equals("/")) result = calculator.divide(firstNumber, secondNumber); else resultStr="not-OK"; numbers.setResult(result); return resultStr; }
llamamosa la capade negocio
y ponemosel resultadoen el backingbean.
Obtenemoslos valoresintroducidospor el usuarioleyéndolos delbacking bean,
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Conversores
• Conversión de formatos entre la vista y el modelo.• Se realiza en la fase Apply Request Value.• Si no se indica nada, JSF realiza una conversión
automática.• Si hay error, se añade un mensaje de error al
contexto para el componente.• Podremos recuperar los mensajes de error en la
vista:• <h:messages /> para recuperar todos• <h:message for=”id_componente” /> para un
componente
22
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Custom converters• Nos permiten cubrir necesidades más específicas• Ej: DNI, pasaporte, número de cuenta...• Un conversor convierte de String a Object y viceversa• Implementa la interfaz Converter• Métodos:• Object getAsObject(FacesContext context, UIComponent component, String newValue): convierte un String en objeto• String getAsString(FacesContext context, UIComponent component, Object value): convierte un objeto a String para mostrarlo por pantalla
23
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Uso de los custom converters
• En el componente
24
@FacesConverter(“especialistajee.DniConverter”)public class DniConverter implements Converter { ...}
<h:inputText value="#{usuario.dni}"> <f:converter converterId="especialistajee.DniConverter"/></h:inputText>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
25
package org.especialistajee.jsf.converter;
//Imports
@FacesConverter(forClass=DniBean.class)public class DniConverter implements Converter { @Override public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException { if(!value.matches("\\d{8}\\w{1}")){ FacesMessage message = new FacesMessage( FacesMessage.SEVERITY_ERROR, "Formato de DNI incorrecto", "Formato de DNI incorrecto"); throw new ConverterException(message); } DniBean dni = new DniBean(); dni.setNumero(value.substring(0, 8)); dni.setLetra(value.substring(8, 9)); return dni; } @Override public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException { DniBean dni = (DniBean) value; return dni.getNumero() + dni.getLetra(); }}
• Declarar en el conversor sobre qué clase actuaremos
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Validación• La validación se encarga de asegurar que los datos introducidos son los
esperados:• El número introducido no puede ser decimal• La contraseña debe tener ocho caracteres• La fecha introducida no puede ser anterior a la actual
• JSF provee tags de validación
26
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
• Uso de los tags de validación:
• Por defecto, la validación se realiza siempre.• Hay casos en que no nos interesa que se realice la
validación (ej: cancelar cualquier acción).• Para saltarnos la validación, hay que indicarlo en la
llamada a la acción:
27
<h:inputText value="#{bean1.amount}" required="true"> <f:validateDoubleRange maximum="1000"/></h:inputText>
<h:commandButton action="pantallaLogin" value="#{msgs.label_cancel}" immediate=”true”/>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Mensajes de los validadores
28
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Personalizar los mensajes de validación
• Crear un fichero ValidationMessages.properties en el paquete raíz de nuestra aplicación
29
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Validación con JSR 303
• JSF 2 se integra con el Bean Validation Framework• Cualquier servidor de aplicaciones lo trae por defecto• En contenedores web: incluir el jar de Hibernate Validator
• Podemos anotar nuestro bean con restricciones de validación
• Ventaja: cambiando el bean, cambiamos la validación en toda la aplicación
• Al igual que en el caso anterior, nos permite personalizar los mensajes de validación
• También podemos especificar mensajes
30
@Size(min=9, max=9, message="{org.especialistajee.longitudDni}")private String dni = "";
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Anotaciones JSR 303
31
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Custom validators
• Al igual que en el caso de los conversores, podemos crearnos nuestros propios validadores
• Deben implementar la interfaz @FacesValidator, que proporciona el método • validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
• Al validador habrá que asignarle un identificador, que invocaremos en la vista
32
<h:inputText id="dniInput" value="#{resetPassController.dni}"> <f:validator validatorId="dniValidator"/></h:inputText>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Ejemplo
33
package org.especialistajee.jsf.validator; import javax.faces.application.FacesMessage;import javax.faces.component.UIComponent;import javax.faces.context.FacesContext;import javax.faces.validator.FacesValidator;import javax.faces.validator.Validator;import javax.faces.validator.ValidatorException; import org.especialistajee.jsf.beans.DniBean; @FacesValidator("dniValidator")public class DniValidator implements Validator{ private static String letras = "TRWAGMYFPDXBNJZSQVHLCKE"; public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { DniBean dni = (DniBean)value; char letraCalculada = letras.charAt(Integer.parseInt(dni.getNumero())%letras.length()); boolean letraOk = Character.toString(letraCalculada).equalsIgnoreCase(dni.getLetra()); if(!letraOk){ FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error en el DNI", "Formato de DNI incorrecto"); throw new ValidatorException(message); } }}
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
34
Demo
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
FacesContext
• Toda petición JSF tiene asociado un contexto, en forma de una instancia de la clase FacesContext.
• Esta clase define un conjunto de métodos que nos permiten obtener y modificar sus elementos:• La cola de mensajes• El árbol de componentes• Objetos de configuración de la aplicación• Métodos de control del flujo del ciclo de vida
35
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Ejemplo de código
package calculator.validator;...import javax.faces.component.UIComponentBase;import javax.faces.component.UIViewRoot;import javax.faces.context.FacesContext;
public class PairNumberValidator implements Validator { public void validate(FacesContext arg0, UIComponent component, " " " Object value) throws ValidatorException { FacesContext context = FacesContext.getCurrentInstance(); UIViewRoot viewRoot = context.getViewRoot(); String ids = getComponentIds(viewRoot); FacesMessage message = new FacesMessage("Componentes: "+ ids); context.addMessage(null,message); ... } }
}
36
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Pantalla
37
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Eventos PhaseEvent
• Se producen antes y después de todas las fases del ciclo de vida de la petición
• Un manejador de este evento debe implementar la interfaz PhaseListener, con los métodos beforePhase() y afterPase()
• Se puede declarar un manejador propio en el fichero faces-config.xml:
38
<lifecycle> <phase-listener> calculator.controller.CalculatorPhaseListener </phase-listener></lifecycle>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Usando componentes en los beans
• Es posible ligar en la página JSF un componente JSF a una propiedad del bean gestionado
• El bean debe tener un campo con un tipo compatible con el componente
39
<h:panelGroup> <h:inputText binding="#{miBean.inputText}" size="30"/> <h:commandLink value="Añadir proyecto" actionListener="#{miBean.addNewProject}" immediate="true"/></h:panelGroup>...<h:selectOneMenu id="project" required="true"" value="#{miBean.project}">" <f:selectItems value="#{miBean.projects}" /></h:selectOneMenu>
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Bean gestionado
40
public class MiBean { ... private UIInput inputText; ... public UIInput getInputText() { return inputText; }
public void setInputText(UIInput inputText) { this.inputText = inputText; } public void addNewProject(ActionEvent event) { String newProject = (String)inputText.getSubmittedValue(); inputText.setSubmittedValue(null); projects.add(newProject); } ...}
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Elementos JSF y componentes
41
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
Componentes JSF
42
Especialista Universitario Java Enterprise
JavaServer Faces © 2011-2012 Depto. Ciencia de la Computación e IA Ciclo de vida JSF
Especialista Universitario Java Enterprise
¿Preguntas?
43