[jsf] java server faces y ajax – parte 2 (2006)
TRANSCRIPT
JavaServer Faces y AJAX – Parte 2
JavaServer Faces y AJAX – Parte 2............................................................................................. 1 Introducción ............................................................................................................................... 2 Ciclo de Vida de una Petición JavaServer Faces...................................................................... 2
Ciclo de Vida de una Petición Inicial...................................................................................... 2 La Fase Restore View en una Petición Inicial .................................................................... 3 La Fase Render Response en una Petición Inicial ............................................................ 4
Ciclo de Vida de una Petición PostBack................................................................................ 7 La Fase Restore View de una Petición Postback .............................................................. 7 La Fase Apply Request Values de una Petición Postback ................................................ 7
Request values vs. Submitted Values ............................................................................ 7 Conversión...................................................................................................................... 7 Conversores Predefinidos............................................................................................... 8 Conversores Definidos por el Usuario ............................................................................ 8 Excepciones durante la Fase de Apply Request Values.............................................. 10
La Fase de Validación en un Petición Postback.................................................................. 11 Validadores predefinidos .................................................................................................. 11 Validadores definidos por el usuario ................................................................................ 12 Método de validación específicos en los backing-beans. ................................................ 12
Actualización del Modelo ..................................................................................................... 13 Backing Beans.................................................................................................................. 13
Invocación a la Aplicación.................................................................................................... 13 La fase RenderResponse en una Petición PostBack .......................................................... 14
Tratamiento de Excepciones ................................................................................................... 15 Un ejemplo............................................................................................................................... 15 Resumen.................................................................................................................................. 17
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Introducción Página 2 de 17
Introducción
Ciclo de Vida de una Petición JavaServer Faces En esta sección describiremos el ciclo de vida de una petición JavaServer Faces. Este ciclo de
vida se divide en fases, las que dependen del tipo de petición. Distinguiremos, en principio,
entre dos tipos de peticiones:
a) la petición inicial: que corresponde a la primera vez que se realiza la petición de una
página JSF.
b) La petición postback: que corresponde a una petición que proviene de una petición
JavaServer Faces anterior sobre dicha página.
Según el tipo de petición, el ciclo de vida varía. La figura 1 Muestra el ciclo de vida completo
de una petición JavaServer Faces.
RestoreView
Apply RequestValues
ProcessValidations
RenderResponse
InvokeApplication
Update ModelValues
ProcessEvents
ProcessEvents
ProcessEvents
ProcessEvents
FacesRequest
FacesResponse
Conversion Errors / Render Response
Validation / ConversionErrors / Render Response
Render Response
ResponseComplete
ResponseComplete
ResponseComplete
ResponseComplete
Figura 1
Ciclo de Vida de una Petición Inicial
Una petición inicial corresponde a la solicitud de una página JSF por primera vez. En este caso,
el árbol de componentes (o vista) debe construirse e inicializarse y no es necesario realizar
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 3 de 17
validaciones o conversiones de los datos, ya que no hay datos a recuperar desde la petición.
La Figura 2 muestra las fases del ciclo de vida que se realizan en una petición inicial.
RestoreView
Apply RequestValues
ProcessValidations
RenderResponse
InvokeApplication
Update ModelValues
ProcessEvents
ProcessEvents
ProcessEvents
ProcessEvents
FacesRequest
FacesResponse
Conversion Errors / Render Response
Validation / ConversionErrors / Render Response
Render Response
ResponseComplete
ResponseComplete
ResponseComplete
ResponseComplete
Figura 2
La Fase Restore View en una Petición Inicial
Durante esta fase, se realiza la creación e inicialización de la vista. Este es un objeto de tipo
UIViewRoot que se almacena en el FacesContext. Este objeto contiene la jerarquía de
componentes de la vista. La figura 3 muestra un ejemplo de la jerarquía de componentes de
una vista.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 4 de 17
View
Component
Component Component Component
Component Component
Faces Context
Figura 3
Posteriormente, se transfiere el control a la fase RenderResponse, mediante la invocación del
método renderResponse(). De esta forma se saltean las fases intermedias.
La Fase Render Response en una Petición Inicial
Durante esta fase se realiza la renderización de la vista. La renderización consiste en la
generación del código para la generación de la respuesta a esta petición. En nuestro caso, el
código generado será HTML.
Ejemplo:
Supongamos el siguiente código JSF
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 5 de 17
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSF Ejemplo</title>
</head>
<body>
<f:view>
<h:form>
<div>
<h:outputLabel value="Código de Usuario"> </h:outputLabel>
<h:inputText id="codigoUsuario" value="#{AltaUsuarioBean.usuario}" ></h:inputText>
</div>
<div>
<h:commandButton action="#{AltaUsuarioBean.enviarAction}" value="enviar">
</h:commandButton>
</div>
</h:form>
</f:view>
</body>
</html>
La jerarquía de los componentes que forman la página JSF es:
f:view
h:form
h:outputLabel h:inputText h:commandButton
Faces Context
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 6 de 17
La renderización a código HTML será la siguiente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form id="_id0" method="post" action="/LifeCycleExample/faces/welcomeJSF.jsp"
enctype="application/x-www-form-urlencoded">
<div>
<label>Código de Usuario </label>
<input id="_id0:codigoUsuario" type="text" name="_id0:codigoUsuario" />
</div>
<div>
<input type="submit" name="_id0:_id5" value="enviar" />
</div>
……………….. </body>
</html>
Note como el <h:form> fue renderizado a una etiqueta <form> HTML, el <h:inputText> fue
renderizado a una etiqueta input HTML y como el <h:commandButton> fue renderizado a una
etiqueta <input type=”submit”> HTML.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 7 de 17
Ciclo de Vida de una Petición PostBack
El ciclo de vida de una petición Postback se ilustra en la Figura 1.
La Fase Restore View de una Petición Postback
Durante esta fase se recupera la vista desde el FacesContext. Esta vista puede ser la inicial o
puede ser una vista actualizada por varias peticiones anteriores.
La Fase Apply Request Values de una Petición Postback
Request values vs. Submitted Values
Es importante distinguir entre los valores de la petición y los valores que se asignan al
componente. La asignación de valores al componente se realiza a través del método decode
del componente. Este método transforma los valores de la petición en valores del componente.
Las siguientes actividades en esta y posteriores fases utilizarán los “submitted values”.
Conversión
Durante esta fase se realiza también la conversión de los submitted values a los tipos de datos
del dominio. Los submitted values, generalmente son de tipo String, mientras que los valores
en el dominio generalmente serán de un tipo de datos diferente. Por ejemplo, considere un
número de teléfono que tiene un submitted value de tipo String en el formato xx-xxxxxxxx y que
en el modelo se trata como un par (Característica, Número).
A esta actividad se le denomina conversión y se especifica mediante conversores. Los
conversores pueden ser predefinidos o definidos por el usuario.
Observación: La decodificación y la conversión son actividades independientes. La
decodificación está asociada a un componente en forma general, mientras que la conversión
está asociada a una instancia particular de un componente. A modo de ejemplo, usted puede
definir asociar conversiones diferentes a distintas instancias de un mismo componente.
Considere dos instancias de un componente inputText. A una puede asociarle un conversor a
BigDecimal y a otra instancia un conversor a Double.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 8 de 17
Conversores Predefinidos
Los conversores predefinidos en la especificación 1.2 de JavaServer Faces se listan en la
Tabla siguiente.
Convertidos Descripción
BigDecimalConverter Convierte un String en un valor de tipo java.math.BigDecimal
BigIntegerConverter Convierte un String en un valor de tipo java.mat.BigInteger
BooleanConverter Convierte un String en un valor de tipo java.lang.Boolean.
ByteConverter Convierte un String en un valor de tipo java.lang.Byte.
CharacterConverter Convierte un String en un valor de tipo java.lang.Character.
DoubleConverter Convierte un String en un valor de tipo java.lang.Double.
FloatConverter Convierte un String en un valor de tipo java.lang.Float.
IntegerConverter Convierte un String en un valor de tipo java.lang.Integer.
ShortConverter Convierte un String en un valor de tipo java.lang.Short.
LongConverter Convierte un String en un valor de tipo java.lang.Long
EnumConverter Convierte un String en un valor de tipo java.lang.Enum.
Si durante el proceso de conversión se produce un error, se lanza una excepción de tipo
ConverterException.
Conversores Definidos por el Usuario
Usted puede definir sus propios conversores. Para ello, debe realizar lo siguiente:
i) Implementar una clase que implemente la clase Converted. Esta clase debe
implementar los métodos getAsObject y getAsString. El método getAsObject
realiza la conversión del dato de tipo String al valor en el tipo de datos que se
desee. Por ejemplo, a un objeto de la clase Teléfono con dos propiedades:
caracteristica y numero. El método getAsString realiza la conversión del tipo de
datos del dominio al tipo String.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 9 de 17
public class TelefonoConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String
newValue) {
//Implementación de la conversion de String a Telefono
}
public String getAsString(FacesContext context,
UIComponent component,
Object value) {
//Implementacion de la conversion de Telefono a String
}
}
ii) Incluir el conversor en el archivo faces-config.xml. Para ello debe declararse el
conversor como:
<converter>
<converter-id>TelefonoConversor</converter-id>
<converter-class>com.sofis.converter.TelefonoConversor</converter-id>
</converter>
iii) Asignar el conversor al componente JavaServer Faces, mediante la etiqueta
f:converter e indicando el converterId asociado
<h:inputText name=”Telefono”>
<f:converter converterId=”TelefonoConverter”/>
</h:inputText>
Nota: Si el componente tiene especificado el atributo immediate en true, durante la fase Apply
Request Values se realiza también la validación de dicho componente. El atributo immediate no
se discute en este artícuo.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 10 de 17
Excepciones durante la Fase de Apply Request Values
Los métodos getAsObject y getAsString pueden lanzar una excepción ConverterException en
caso que la conversión no pueda realizarse.
Los constructores para esta excepción son:
1. ConverterException()
2. ConverterException( FacesMessage mensaje)
3. ConverterException(FacesMessage mensaje,Throwable causa)
4. ConverterException(String mensaje)
5. ConverterException(String mensaje, Throwable causa)
6. ConverterException(Throwable causa)
Ejemplo:
If (newValue.length() < 4) {
FacesMessage mensaje=new FacesMessage();
mensaje.set (“El largo debe ser mayor a 4”);
throws ConverterException(mensaje);
}
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 11 de 17
La Fase de Validación en un Petición Postback
Durante esta fase se realiza la validación de los datos. Las validaciones pueden especificarse,
al menos de tres formas:
a) mediante validadores predefinidos
b) mediante validadores definidos por el usuario
c) mediante métodos de validación específicos
A continuación se describen cada uno de ellos.
Validadores predefinidos
Los validadores definidos en la especificación 1.2 de JavaServer Faces son:
• DoubleRangeValidator – Valida que el valor local del componente sea numérico de tipo
double y que este esté entre un mínimo y un máximo especificados como parámetros.
• LongRangeValidator – Valida que el valor local del componente sea numérico de tipo
long y que esté entre un mínimo y un máximo especificados como parámetros.
• LengthValidator – El valor debe ser de tipo String y su largo debe estar entre un mínimo
y un máximo especificados como parámetros.
La asignación de uno de estos validadores a una instancia de un componente se realiza como
se muestra a continuación.
<h:inputText id=”codigoUsuario”
<f:validateLength minimum=”6” maximum=”10”/>
</h:inputText>
<h:inputText id=”edad”
<f:validateLongRange minimum=”18” maximum=”60”/>
</h:inputText>
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 12 de 17
Validadores definidos por el usuario
Usted puede crear sus propios validadores. Los validadores son clases que implementan la
interfaz Validator y su método validate. En este método usted puede realizar todas las
validaciones que considere necesarias. Para poder utilizar estos validadores, debe declararlos
en el archivo faces-config.xml.
public class TelefonoValidator implements Validator {
public void validate(FacesContext context, UIComponent componente, Object valor) {
// Acá implementa la validación
}
}
<faces-config>
<validator>
<validator-id>ValidacionTelefono<validator-id>
<validator-class>com.sofis.validators.TelefonoValidator</validator-class>
</validator>
</faces-config>
Método de validación específicos en los backing-beans.
Usted puede definir un método de validación específico a aplicar a un componente en un
backing bean. Este método puede tener cualquier nombre, pero debe tener la misma signatura
que el método validate de la interfaz Validator.
La clase que implementa este método debe ser declarada como un managed-bean en el
archivo faces-config.xml.
<faces-config>
<managed-bean>
<manager-bean-name> </manager-bean-name>
<managed-bean-class> </managed-bean-class>
<managed-bean-scope> </managed-bean-scope>
</managed-bean>
</faces-config>
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 13 de 17
En la página JSF usted debe indicar este validador utilizando la siguiente declaración:
<h:inputText id=”telefono” validator=”#{backingBean.validarTelefono}”/>
donde backingBean es el valor del elemento managed-bean-name definido en el archivo faces-
config.xml.
Nota: Observe que al utilizar esta forma de validación el backing bean queda ligado a la API
Java Server Faces. Dado que es necesario importar en el backing-beans clases de la misma.
Actualización del Modelo
Durante esta fase se realiza la actualización del modelo. Al inicio de esta fase se puede
asegurar que los valores de la vista han sido convertidos y validados según las reglas
especificadas.
Backing Beans
Un backing bean es un componente JavaBean asociado con los componentes UI usados en
una página. En los backing beans se definen las propiedades del componente y los métodos
asociados al mismo. Esta fase ocurre después de la conversión y la validación. Por lo tanto, los
valores con que trabaja esta fase son los submitted values y son válidos (a nivel de form). Sin
embargo, pueden no ser válidos desde el punto de vista de la capa de negocio.
Durante la fase de actualización del modelo se actualizan los valores de los backing bean a
partir de los valores de la vista. Los backing beans (también conocidos como manager beans)
deben ser declarados en el archivo faces-config.xml, como se describió anteriormente.
Invocación a la Aplicación
En esta fase se resuelven las actividades correspondientes a las acciones definidas para el
componente y se resuelve la navegación.
Las acciones pueden definirse a través de métodos en el backing bean. Por ejemplo, que la
acción asociada a un botón sea un método de un backing bean.
<h:commandButton action=”#{MiBean.miMetodo}” />
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Ciclo de Vida de una Petición JavaServer FacesPágina 14 de 17
Este método resolverá la lógica correspondiente a la aplicación (almacenar valores en la base
de datos, realizar cálculos, etc.) y determinará la navegación resultante.
La navegación define la página resultante desde una página dada, frente a determinado caso.
Por ejemplo, desde la página entrada.jsp ante el caso “ok”, la página resultante es
“respuesta.jsp”. Esta navegación se define en el faces-config.xml como se muestra a
continuación.
<faces-config>
<navigation-rule>
<from-view-id>/entrada.jsp</from-view-id>
<navigation-case>
<outcome-from>ok</outcome-from>
<to-view-id>/respuesta.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
El método asociado a la acción, realizará
return “ok”; Esto indica cuál es la siguiente página en el ciclo. En caso de no existir un “outcome-from”
definido para el valor devuelto por el método asociado a la acción, la página resultante será la
misma desde donde se realizó la petición.
La fase RenderResponse en una Petición PostBack Durante esta fase se realiza la generación del código de la respuesta al usuario. A partir de los
datos definidos en los backing bean y de los componentes UI de la vista, se genera el código
correspondiente. De esta forma, un componente UI inputText puede ser generado como una
etiqueta <input type=”text”…/> en el código HTML o una etiqueta <textarea> </textarea> según
se haya definido la renderización.
El trabajo con renderización presenta varias ventajas:
a) Independiza la lógica del trabajo con componentes de la presentación del componente.
Se pueden realizar todas las fases previas sin importar si se está trabajando con
HTML, con WML o con voz.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Tratamiento de Excepciones Página 15 de 17
b) Permite definir múltiples renders para un mismo tipo de salida. Una lista de valores
podría ser generada en HTML como un listbox, como una secuencia de check buttons,
etc., según sea el caso.
Los procesos de renderización son internos al componente. Si el usuario define sus propios
componentes, puede definir cómo estos serán renderizados.
Tratamiento de Excepciones Durante cada una de las fases del ciclo de vida de una petición JavaServer Faces pueden
lanzarse excepciones. Estas excepciones son tratadas a continuación de cada fase por un
proceso de manejo de eventos. Durante este proceso se puede ejecutar directamente el
método renderResponse. Este método causa que se salteen todas las fases siguientes en el
ciclo de vida hasta la fase de RenderResponse. El método responseComplete causa que se
finalice el ciclo de vida de esa petición.
Este tema será tratado con mayor profundidad en los próximos artículos.
Un ejemplo Considere un componente correspondiente a una dirección con Código Postal, Ciudad y País.
El usuario entra el valor correspondiente al Código Postal y a partir del mismo se completan los
valores de Ciudad y País. Para obtener estos datos, se consulta a una base de datos que
proporciona estos valores.
Página JSP
<f:view>
<h:outputLabel>Código Postal</h:outputLabel>
<h:inputText name=”codigoPostal”
value=”#{direccion.codigoPostal}”
onBlur=”#{direccion.actualizar}” />
<h:outputLabel>Ciudad: </h:outputLabel>
<h:outputLabel value=”#{direccion.ciudad}”/>
<h:outputLabel>Pais: </h:outputLabel>
<h:outputLabel value=”#{direccion.pais}”/>
</f:view>
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Un ejemplo Página 16 de 17
public class Convertir implements Converter {
public Object getAsObject( ) {
Return newValue.getPrefix(5);
}
}
Backing Bean
Public class Direccion {
String codigoPostalBasico;
String ciudad;
String pais;
// se omiten los métodos getter y setter
public void validate(FacesContext context,
UIComponent component,
Object value) {
If (codigoPostal no existe) {
FacesMessage mensaje=new FacesMessage();
mensaje.set (“Ese código postal no existe.”);
throws ConverterException(mensaje);
}
Public void actualizar() {
//Consultar a la BD; ciudadBD, paisBD;
Ciudad=ciudadBD;
Pais=paisBD;
return “ok”;
}
}
Nota: En este caso el texto del mensaje está incluido en el texto. En los futuros artículos se
discutirán estrategias para crear aplicaciones localizables.
www.sofis-solutions.com
JavaServer Faces y AJAX – Parte 2 - Página 17 de 17
Resumen En este artículo se presentó el ciclo de vida una petición JavaServer Faces y se distinguió entre
los casos de petición inicial y postback. Se analizaron las distintas fases del ciclo de vida y se
presentaron cuatro conceptos importantes:
a) conversión: transformación de los datos recibidos en la petición a los datos necesarios
en el dominio de la aplicación.
b) Validación: validación de los datos, luego de realizar la conversión.
c) Backing bean: Bean que almacena las propiedades de los componentes UI de la
página y los métodos asociados.
d) Renderización: Generación del código de la respuesta a partir de los datos de la vista
y del modelo.
En el próximo artículo, se profundizará sobre la técnica AJAX y se presentarán distintas
estrategias para trabajar con componentes JSF que incluyan la técnica AJAX.
Ing. Santiago Atella Ing. Gustavo A. Cirigliano
Noviembre 2006.