JSF Navegación Dinámica

En los últimos capítulos del libro hemos trabajado con JSF como framework de capa de presentación y hemos construido varias páginas  entre las que navegamos .Sin embargo la navegación que el libro define es una navegación estática ya que esta completamente ligada a la estructura de las páginas. A continuación se muestran dos páginas ligadas de forma estática.

La página de inicio contiene el siguiente formulario JSF con un único boton:

<h:form>
<h:commandButton id=”boton” value=”aceptar” action=”resultado”/>
</h:form>

Al solicitar la página al servidor nos mostrará la siguiente información.

Al pulsar el boton el framework de JSF nos enviara a la pagina xhtml que este definida en el atributo action  (action=”resultado”) en este caso la página de resultado.xhtml que nos imprimirá el siguiente mensaje.

Aunque el funcionamiento es correcto según la aplicación aumente de tamaño necesitaremos una forma de navegar entre paginas JSF mas flexible .Para ello usaremos el fichero faces-config.xml y sus capacidades a la hora de definir reglas de navegación. Recordemos que este fichero se encuentra ubicado en el directorio WEB-INF.

Una vez que hemos definido este fichero .Vamos a utilizar la navegación dinamica apoyandonos en las siguientes 3 páginas.

La página de inicioNavegación.xhtml  es nuestro punto de partida y para decidir que página de destino carga se apoyará en un ManagedBean definido por la aplicación. En nuestro caso hemos decidido denominar a este ManagedBean “BeanDecision”

El código de este ManagedBean es realmente sencillo:

package com.arquitecturajava.bean;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class BeanDecision {

private String nombre;

public String getNombre() {
 return nombre;
 }

public void setNombre(String nombre) {
 this.nombre = nombre;
 }

public String decide() {

if (nombre.equals("cecilio")) {

return "exito";

} else {

return "fallo";

}

}
}

Una vez hemos definido el ManagedBean podemos solicitar la página “inicioNavegacion.xhtml”  la cual incluye una caja de texto que podemos rellenar.

Si revisamos el código fuente de esta página podremos ver como el botón aceptar del formulario esta ligado a un método concreto del ManagedBean

<h:form>
<h:inputText value=”#{beanDecision.nombre}”/>
<h:commandButton id=”boton” value=”aceptar”  action=”#{beanDecision.decide}”/>
</h:form>

El método “decide” nos devuelve “exito” o “fallo” dependiendo del valor de la cadena que este ligada al atributo “nombre” del ManagedBean. Ahora bien esto no nos solventa del todo la navegación entre las distintas páginas . Para que el framework JSF pueda dirigirmos a las páginas que nosotros queremos .deberemos definir unas reglas de navegación básicas a nivel de faces-config.xml.

<navigation-rule>
<from-view-id>/inicioNavegacion.xhtml</from-view-id>
<navigation-case>
<from-outcome>exito</from-outcome>
<to-view-id>/resultadoOK.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>fallo</from-outcome>
<to-view-id>/resultadoFallo.xhtml</to-view-id>
</navigation-case>
</navigation-rule>

En este caso la regla de navegación es muy sencilla por un lado definimos cual es la página de partida.

<from-view-id>/inicioNavegacion.xhtml</from-view-id>  

Por otro lado definimos el outcome o resultado que esperamos.

<from-outcome>exito</from-outcome>

Una vez el outcome esta claro  simplemente definimos la vista destino a la que deseamos ir basandomos en ese outcome

<to-view-id>/resultadoOK.xhtml</to-view-id>.

A partir de ahora podremos eliminar la navegación estática de las páginas y centrarnos en una navegación dinámica mucho mas flexible.

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

About Cecilio Álvarez Caules

Cecilio Álvarez Caules Sun Certified Enterprise Architech (J2EE/JEE).

21 Responses to JSF Navegación Dinámica

  1. Jorge 9 Noviembre, 2016 at 17:27 #

    Hola, recien empiezo en el mundo de jsf y tengo algunas dudas. Tengo un problema al actualizar una tabla, esa tabla jala datos de una base de datos, antes de ingresar a esa pagina tengo un login quiero que despues de pasar ese login la tabla cargue los datos de la bd. La única manera con la que puede traer los datos es con un boton desde la misma pagina. Alguna idea para poder lograr esto? Muchas gracias de antemano.

    • Jorge 9 Noviembre, 2016 at 18:13 #

      lo que quiero es que con el botón de login cargue los datos en la tabla.

      • Cecilio Álvarez Caules 13 Noviembre, 2016 at 13:06 #

        Pues tendrás que invocar a un managedbean que este cargue los datos y redirigir a una vista que los presenta 🙂

  2. Alberto 13 Septiembre, 2016 at 19:24 #

    Excelente página. Una consulta. Cuando navegas entre páginas, la URL no muestra la página en la que te encuentras, sino la página anterior. Entonces, sucede que al dar F5, se actualiza la página que muestra la URL y no la que se está visualizando. Es esto un bug de JSF o sabes si tiene alguna solución. Muchas gracias y muchos éxitos.

  3. Jose Manuel 5 Abril, 2016 at 1:41 #

    Hola amigo buen día,

    Estoy tratando de realizar la navegación dinámica pero con un layoutUnit y me manda el siguiente error:

    UI Layout Initialization
    Error The center-pane element does not exist.
    The center-pane is a required element

    Sabes a que se refiere este error:

    Saludos!!!

    • Cecilio Álvarez Caules 5 Abril, 2016 at 17:16 #

      parece que es un fallo en el layout como si faltara un contenedor , pero no te se decir más

  4. jhair 26 Febrero, 2016 at 15:48 #

    excelente muchas gracias!!!

    • Cecilio Álvarez Caules 27 Febrero, 2016 at 13:55 #

      de nada 🙂

  5. Max 19 Febrero, 2016 at 21:31 #

    Excelente explicación.. Tengo una duda y que no he podido resolver, para el caso de cuando yo cierro sesion y no importando donde este, me pueda redireccionar al Login. Como lo puedo hacer? Tengo que establecer una regla por cada una de las pagina que tengo, la cual me redireccione al Login? tengo paginas que no se encuentran en la raiz, sino en subcarpetas.

    De antemano Gracias

    • Cecilio Álvarez Caules 23 Febrero, 2016 at 14:40 #

      Normalmente eso se hace a nivel de seguridad no de JSF puro , en tu caso se haría con JAAS o Spring Security

  6. Marco Antonio 4 Agosto, 2014 at 2:14 #

    Buena tarde.

    Tengo un problema con la navegación de una pagina cuando retorno del método la respuesta para saber a que pagina debo ir , el error es “No se puede encontrar el caso de navegación coincidente del ID de vista”.

    tengo la regla de navegacion :

    /FormLoguin.xhtml

    #{formLoguin.loguinUsuario}
    ACTIVO
    /PagPrincipal.xhtml

    y el metodo

    public String loguinUsuario(){
    UsuariosDAO usuario = new UsuariosDAO();
    String msgLoguin = usuario.loguinUsuario(this.usuario, this.contrasena);
    this.msgError = msgLoguin;
    return msgLoguin;
    }

    Cuando el caso es “ACTIVO” me redirecciona a la pagina correctamente , pero cuando la respuesta es diferente me genera el mensaje que deseo en la etiqueta pero adicionalmente me sale el mensaje “No se puede encontrar el caso de navegación coincidente del ID de vista ‘/FormLoguin.xhtml’ para la acción {1}’ con el resultado ‘{2}'” .

    Cual podria ser el problema .

    Muchas gracias por su atencion.

    • Cecilio Álvarez Caules 5 Agosto, 2014 at 8:57 #

      Añade el otro caso de navegación para la situación NOActivo y devuelve tambien un valor para ella

  7. Emmanuel 22 Abril, 2014 at 18:41 #

    a pesar de que la navego hacia la segunda pagina, la dirección es la de la primera, igual como se ve en tus dos imágenes (02Inicio y 03Resultado) tiene inicio.xhtml como hago para corregir esto? porque tengo un boton que regresa a la pagina anterior (onclick=”history.back()”) y no regresa pero si me cambia la direccion

    • Cecilio Álvarez Caules 23 Abril, 2014 at 18:53 #

      prueba a usar la etiqueta “redirect” a nivel de JSF .Deberia soportarte history back 🙂

      • Emmanuel 24 Abril, 2014 at 16:26 #

        Gracias!! leí tu libro y es excelente!!

  8. nelson 13 Diciembre, 2013 at 23:18 #

    Cómo puedo definir que una vista A.xhtml sólamente sea renderizada o “accedida” si y solamente si, vengo de una vista B.xhtml o de la misma vista A.xhtml. Es decir, si vengo de una vista C.xhtml o de una dirección externa, que la vista no sea renderizada o me envíe a otra vista, por ejemplo B.xhtml?

    • Cecilio Álvarez Caules 14 Diciembre, 2013 at 11:00 #

      Recuerda que JSF soporta expresiones condicionales tipo

      submit
      #{model.booleanValue}
      #{model.successOutcome}

      Lo cual te permitiría cosas del estilo que comentas

  9. andres 30 Octubre, 2013 at 21:52 #

    muy buen tutorial pero tengo una duda, a que libro se refieren?? o de uqe libro lo sacas 😀

    • Cecilio Álvarez Caules 31 Octubre, 2013 at 10:25 #

      Del libro de Arquitectura java solida que te puedes bajar de la página principal del blog 🙂

  10. Nelson 8 Septiembre, 2013 at 18:23 #

    Bárbaro. Muy puntual, muy sencillo y muy concreto. Gracias por compartir.

Deja un comentario