Navegación entre páginas con JSF

De ChuWiki

Introducción[editar]

Usando java beans en la parte del servidor podemos decidir cómo se navega entre las páginas del navegador en función de los datos introducidos por el usuario o cualquier circuntancia que podamos programar. La idea básica es que en un bean de java del lado del servidor pongamos un método sin parámetros que devuelva un String. El botón h:commandButton de un formulario (o un h:commandLink) llamarán a este método y será este método el que devuelva en el String cual es la siguiente página a visualizar.

Los componentes de la página[editar]

Supongamos el siguiente formulario

<h:form>
   <h:inputText id="idNumero" required="true"
      value="#{holaMundo.numero}">
   </h:inputText>
   <h:commandButton action="#{holaMundo.navega}" value="Enviar">
   </h:commandButton>
</h:form>

Es un formulario con un campo de texto h:inputText asociado al atributo holaMundo.numero (un atributo entero en el bean HolaMundo.java). En el botón de envío hemos puesto una llamada al método navega() ( action="#{holaMundo.navega}" ) que pondremos en ese HolaMundo.java, de forma que al pulsar el botón de "Enviar", se llamará a este método.

El bean[editar]

El bean HolaMundo.java puede ser como este

package com.chuidiang.ejemplos.jsf;


import javax.faces.bean.ManagedBean;

@ManagedBean
public class HolaMundo {

   private int numero = 4;

   public int getNumero() {
      return numero;
   }

   public void setNumero(int numero) {
      this.numero = numero;
   }

   public String navega() {
      if (numero % 2 == 0) {
         return "par.xhtml";
      } else {
         return "impar.xhtml";
      }
   }

}

Símplemente comprueba si el número es par o impar, para devolver la página par.xhtml o impar.xhtml. De esta forma, al pulsar el botón, se verá una página u otra según el número introducido por el usuario sea par o impar. Ojo, es importante que las páginas existan, porque JSF es demasiado listo y si no existen, nos dejará en la página actual.

Definir rutas de navegación[editar]

No es estrictamente necesario, pero podemos definir rutas de navegación en el fichero WEB-INF/faces-config.xml. Podemos poner, por ejemplo, algo como esto

<?xml version="1.0" encoding="UTF-8"?>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/faces/hola.xml</from-view-id>
		<navigation-case>
			<from-outcome>par</from-outcome>
			<to-view-id>/faces/par.xml</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-outcome>impar</from-outcome>
			<to-view-id>/faces/impar.xml</to-view-id>
		</navigation-case>
	</navigation-rule>

</faces-config>

Creamos una regla de navegación <navigation-rule>. En ella decidimos cual es la página de origen <from-view-id> (/faces/hola.xml en nuestro ejemplo) y para cada una de las posibles páginas destino ponemos una especie de identificador <from-outcome> y el destino <to-view-id>.

La modificación que debemos hacer en nuestro bean, es que en vez de devolver directamente en el String la página xhtml, nos basta con devolver el <from-outcome> correspondiente, es decir

   public String navega() {
      if (numero % 2 == 0) {
         return "par";
      } else {
         return "impar";
      }
   }

Podemos simplificar el asunto aún más. Definiendo las rutas de navegación no es necesario que el String nos lo devuelva un bean. Podemos poner el <from-outcome> directamente en la página xhtml (aunque entonces la navegación será fija y no habrá ningún tipo de decisión sobre la marcha de qué página va después. Quedaría así

<h:form>
   <h:inputText id="idNumero" required="true"
      value="#{holaMundo.numero}">
   </h:inputText>
   <h:commandButton action="par" value="Enviar">
   </h:commandButton>
</h:form>