Paso de parámetros por GET con JSF 2

Los que hayan usado JSF en su primera versión saben perfectamente que JSF funciona casi de manera exclusiva con peticiones de tipo POST. Las peticiones de tipo GET requiren algunos "trucos". Esto dificulta algunas cosas, una de ellas, bastante básica, es entrar en el "ciclo" JSF mediante peticions HTTP de tipo GET que lleven parámetros.

Por suerte en la versión JSF 2 se ha mejorado este aspecto. Veamos algunas consideraciones al respecto.

La etiqueta <h:link> nos permite generar un enlace para realizar una petición de tipo GET. Podemos añadir parámetros anidando etiquetas <f:param>:

<h:link outcome="/vistas/juegoArmaduras.faces">  
  <f:param name="nivel" value="PRINCIPIANTE"/>
  <div class="bigbutton">Principiante</div>
</h:link>  

Para recoger el parámetro recibido como una propiedad de bean necesitamos indicar en la página de destino el enlace entre el nombre del parámetro y qué propiedad de qué bean queremos modificar. Utilizamos una sección <f:metadata> para ello.

<f:metadata>  
   <f:viewParam name="nivel" value="#{juegoArmaduras.nivel}"/>
</f:metadata>  

Es importante tener en cuenta que la sección <f:metadata> sólo puede aparecer en la página .xhtml de primer nivel, no en una incluida. Esto es especialmente importante ya que si utilizamos facelets quizás estemos utilizando plantillas. A mi me provocó algunas horas de incomprensión ya que no me funcionaba. Al final encontré el detalle gracias a la genial stackoverflow.

El problema del postback

Al entrar en la vista se ejecuta antes setNivel del bean JuegoArmaduras (@ViewScoped) con el nivel pasado por parámetro. En una primera prueba nos parecerá que funciona perfectamente pero dependiendo de qué haga ese método podemos tener algunos efectos secundarios no deseados. Una revisión más concienzuda nos revela que el método se ejecuta en cada petición POST adicionalmente a la primera. Incluyendo las peticiones Ajax. Por suerte la red vuelve al rescate y en este artículo podemos encontrar la descripción detallada del problema así como ideas fáciles para corregirlo.