Peticiones GET en JSF2: mapear parámetros y gestionar eventos de página.

3
24612

Peticiones GET en JSF2: mapear parámetros y gestionar eventos de página.

0. Índice de contenidos.


1. Introducción

Inspirados en los «parámetros de página» que proporciona Jboss Seam, JSF2 nos brinda el concepto de «parámetros de la vista» que permiten de una manera sencilla y de forma declarativa, mapear
parámetros de la request contra propiedades de un managed bean a través del lenguaje de expresiones.

Con los «parámetros de la vista» se cubre un vacío que existía en JSF1.2, puesto que el ciclo de vida de una petición JSF solo se cubría completamente con peticiones POST provocadas por la interacción
con componentes de tipo ActionSource (<h:commandButton /> o <h:commandLink />).

Ahora, con JSF2 y los componentes <h:link /> y <h:button /> se pueden lanzar eventos dentro del ciclo de vida de JSF a través de peticiones GET y con ello:

  • evitar los forwards a nivel de servidor,
  • forzar un cambio en la url, y
  • hacer la url bookmarkable.

En este tutorial vamos a ver como hacer uso de dichos componentes, cómo mapear los posibles parámetros y, por último, como forzar la ejecución de un evento dentro del ciclo de vida de la petición GET.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 17′ (2.93 GHz Intel Core 2 Duo, 8GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.1
  • JSF2 (Mojarra 2.1.2)
  • Tomcat 7.0.6


3. Los componentes <h:link /> y <h:button />.

Como hemos comentado los componentes <h:link /> y <h:button /> permiten realizar peticiones JSF a través de GET y como se enganchan con las reglas de navegación, hacer uso de los mismos es tan sencillo como esto:


	<h:button value="A la página 2" outcome="page2" />
	<!-- renderizará: <input type="button" value="A la página 2" onclick="window.location.href='/context/page2.xhtml'; return false;"> -->
	
	<h:link value="A la página 2" outcome="page2"> 
		<f:param name="entityId" value="#{entity.id}" />
	</h:link>
	<!-- renderizará: <a href="/contexto/page2.xhtml?entityId=1">link -->

Lo anterior no implica que nuestros fomularios JSF se puedan ahora enviar por GET, en la petición que lanzan estos nuevos componentes solo viajarán los parámetros que indiquemos explícitamente.

Podemos, además, propagar los parámetros de una petición a la siguiente incluyendo los «parámetros de la vista» en estos componentes con el atributo includeViewParams=»true».
Con ello, en la renderización de los componentes se analizan los metadatos de la siguiente vista y se generan en la url de la petición los nombres y valores de los parámetros de la petición actual para que sean mapeados también en la siguiente.


4. Mapear parámetros de la petición.

Con la posibilidad de mapear parámetros de la request contra propiedades de un managed bean, aparte de hacer uso de los componetes <h:link /> y <h:button /> también estamos abriendo la posibilidad de enviar datos desde formularios no JSF a páginas JSF.

Como en el caso anterior, es tan simple como incluir la siguiente sección en la página que queremos que recoja los parámetros de la petición.

<f:metadata>
    <f:viewParam name="entityId" value="#{editView.id}" />
    <f:viewParam name="pageId" value="#{editView.pageId}" />
</f:metadata>

Con ello, frente a una petición del tipo page1.xhtml?entityId=8&pageId=1 se invocarán a los métodos setEntityId y setPageId de managedBean EditView para asignarle los valores de dichos parámetros.

Además del mapeo, también podemos añadir obligatoriedad y conversión de dichos parámetros dentro del ciclo de vida de la petición.

<f:metadata>
    <f:viewParam name="entityId" value="#{editView.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>

La sección <f:metadata, por convención, se suele incluir antes del componente <h:head.


5. Gestión de eventos de página.

Por último, podemos declarar un método del controlador para la gestión del evento de carga de la página de modo que, antes de renderizar la vista, dentro del ciclo de vida de JSF, se invocará al mismo despúes de «setear» los «parámetros de la vista», como hemos visto en el punto anterior.

<f:metadata>
    <f:viewParam name="entityId" value="#{editView.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:event type="preRenderView" listener="#{editView.postLoad}" />
</f:metadata>

Entendemos que podríamos tener la siguiente gestión de eventos y propiedades dentro del Managed Bean.

@ManagedBean
@RequestScoped
public class EditView{

	@ManagedProperty(value="customerRepository")
	private CustomerRepository customerRepository;
	
	private Customer customer;
	
	private Long id;
	
	public void setId(Long id){
		this.id = id;
	}

	public void setCustomerRepository(CustomerRepository customerRepository){
		this.customerRepository = customerRepository;
	}
	
	public Customer getCustomer(){
		return customer;	
	}
	
	public void postLoad(){
		customer = customerRepository.getById(id);
	}
}

El método postLoad será invocado despúes de los métodos set declarados en los metadatos y antes de renderizar la vista.


6. Referencias.

  • http://blogs.oracle.com/rlubke/entry/jsf_2_0_bookmarability_view


7. Conclusiones.

Si con Jboss Seam disponíamos de la misma funcionalidad dentro de la declaración de las reglas de navegación (pages.xml) con JSF2 podemos hacer uso de una funcionalidad similar usandolo en componentes visuales y declaración de metadatos.

Es la diatriba de siempre, tenerlo todo centralizado en un único fichero o declarado allí donde se usa. Para gusto los colores y, si me preguntas, me decanto por lo segundo 😉

En nuestros proyectos le estamos dando una aplicación práctica inmediata para separar la dependencia entre controladores (managed beans) y permitir el marcado de urls desde un primer momento; teniendo en cuenta que en los parámetros que viajan vía GET no debemos exponer lógica de negocio!.

Un saludo.

Jose

jmsanchez@autentia.com

3 COMENTARIOS

  1. Muy buen tutorial, Yo obtenía los parametros desde el bean escribiendo un monton de codigo, aprendiendo esto me simplificare bastante algunas tareas que tengo que realizar.

  2. Hola, tengo una gran duda y necesito de la ayuda de todos.

    Haber tengo una app web JSF (Un cajero) en la cual estoy implementando un procesador de pago (Skrill Monedero) Ya hice la parte del Request en donde envío los datos del cliente a Skrill ahora una vez dentro cuando el usuario realice el pago el servidor de ellos me debe de dar una respuesta con el detalle de la transacción, es decir me harán un Standard HTTP Post a una URL definida que le debería de pasar en el Request y donde debería luego de redirigirle al usuario a una pantalla que muestre el resultado.

    Mi pregunta es como creo esa URL de tal manera que no haya complicaciones cuando ellos hagan un post a esa URL, hice un WS URL(Previamente probado) que recibe un json. Le pase en el request pero no lo llaman, como tendría que ser esa URL? un XHTML? En JSF como recuperó un Post?

    Siempre eh hecho la típica comunicación cliente que envía request al servidor y el envía un response, pero ahora el servidor es el que me hace un Post!!!

    Como hago esto mi app Web es JSF2.2.

    Ayudenme por favor

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad