JSF – cómo capturar eventos del Ciclo de Vida JSF

En el siguiente ejemplo implementamos un PhaseListener para poder visualizar las ejecuciones de validaciones y acciones y el momento en que lo hacen con respecto a las fases y eventos del Ciclo de Vida JSF.

Los PhaseListeners se pueden usar en aplicaciones JSF para capturar y responder a eventos que ocurren durante el ciclo de vida de una aplicación web. Con este mecanismo, los desarrolladores pueden ejecutar acciones específicas en ciertas fases, incluso antes y después del renderizado. Estos listeners también son útiles para rastrear las interacciones de los usuarios y reportar datos para analítica.

Para implementar un PhaseListener en un proyecto JSF, debe implementar la interfaz javax.faces.event.PhaseListener y registrarla en el archivo de configuración de la aplicación JSF. Una vez registrado, el framework invocará automáticamente al listener durante la fase especificada del ciclo de vida.

Es importante tener en cuenta que el uso de demasiados listeners puede afectar el rendimiento de la aplicación, por lo que se recomienda usar solo los necesarios.

Desarrollo de la aplicación

La página contiene un formulario de productos que se almacenan en la tabla que se encuentra en la parte inferior.

<h:form>
    <h:panelGrid columns="2">
        <h:outputLabel value="Codigo" for="codigo" />
        <h:inputText id="codigo" value="#{productosManagedBean.producto.codigo}" />
        <h:outputLabel value="Nombre" for="nombre" />
        <h:inputText id="nombre" value="#{productosManagedBean.producto.nombre}">
            <f:validator validatorId="SampleValidator" />
        </h:inputText>
        <h:outputLabel value="Precio" for="precio" />
        <h:inputText id="precio" value="#{productosManagedBean.producto.precio}" />
        <h:commandButton value="Agregar" action="#{productosManagedBean.agregarProducto()}" />
        <h:commandButton value="Cancelar" />
    </h:panelGrid>
</h:form>

Notar que el campo Producto contiene un validador que se ejecutará en la Fase correspondiente, como se verá más adelante.

El siguiente es el listener de los eventos del Ciclo de Vida JSF, que debe implementar la interfaz javax.faces.event.PhaseListener. En este caso simplemente escribe en consola el nombre de la próxima fase a ejecutarse.

public class FacesPhaseListener implements PhaseListener {
	@Override
	public void afterPhase(PhaseEvent event) {
		
	}
	
	@Override
	public void beforePhase(PhaseEvent event) {
		System.out.printf("-> beforePhase: %s%n", event.getPhaseId());
	}
	@Override
	public PhaseId getPhaseId() {
		return PhaseId.ANY_PHASE;
	}
}

Se debe registrar el listener en la aplicación agregando la siguiente configuración en el archivo faces-config.xml:

<lifecycle>
	<phase-listener>listener.FacesPhaseListener</phase-listener>
</lifecycle>

El siguiente es el Managed Bean. El método agregarProducto() es invocado por el CommandButton. El mismo se encarga de agregar un objeto Producto a la lista que nutre a la tabla que se dibuja en la parte inferior.

@ManagedBean(name="productosManagedBean", eager = true)
@ViewScoped
public class ProductosManagedBean {
	private List<Producto> productos;
	private Producto producto;
	
	@PostConstruct
	public void init() {
		System.out.println("ProductosManagedBean.init()");
		productos = new ArrayList<Producto>();
		producto = new Producto();
	}
	
	public String agregarProducto() {
		System.out.println("ProductosManagedBean.agregarProducto()");
		productos.add(producto);
		producto = new Producto();
		return "";
	}
    //getters y setters
}

Ejecución de la aplicación

En la aplicación el formulario se visualiza como a continuación:

Una vez realizada la carga de un producto podemos ver en la consola las fases por las que ha pasado la aplicación y los métodos que han sido ejecutados.

Eventos del Ciclo de Vida JSF log

En la imagen anterior podemos ver que:

  • Luego de iniciada la fase PROCESS_VALIDATIONS es invocado el método validate() de nuestro Validator.
  • Luego de iniciada la fase INVOKE_APPLICATION es invocado el método agregarProducto() del Managed Bean.

Pueden haber casos en que sea necesario evitar parte de las fases del Ciclo de Vida. Por ejemplo, si en la aplicación ingreso en la descripción la palabra ‘cafe’ (que a los fines de ejemplificar no es admitida por el validador) y hago click en Cancelar, se visualizará el mensaje de error devuelto por el validador.

Eventos del Ciclo de Vida JSF input

Esto se debe a que, si bien el botón cancelar no realiza ninguna función, el formulario es enviado y el Ciclo de Vida es ejecutado. Para evitar esto usamos el atributo immediate.

<h:commandButton value="Cancelar" immediate="true" />

Una vez ejecutado, en consola se visualizará:

Eventos del Ciclo de Vida JSF log 2

En donde se verifica que se han ejecutado las fases RESTORE_VIEW, APPLY_REQUEST_VALUES y RENDER_RESPONSE, salteando las validaciones.

Conclusión

Los PhaseListeners proporcionan una forma flexible y completa de manejar eventos y modificar el comportamiento del framework JSF. Al aprovechar este mecanismo, los desarrolladores pueden mejorar la experiencia del usuario y recopilar datos importantes para el análisis.

Artículos relacionados


Te puede interesar:

Autenticación en JSF

Ejemplo básico de autenticacion en JSF mediante la implementación de una página de login de usuario.

Seguir leyendo →

Arquitectura y Ciclo de Vida JSF

Cómo funciona el ciclo de vida de una aplicación JSF. En el artículo relacionado se cubre el manejo de eventos.

Seguir leyendo →