Navegación entre páginas con JSF
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.
[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>