Tabla de Contenidos

Gestión de la navegación

Gracias a JBoss Seam el control de la navegación entre páginas se hace más rico y flexible. No solo tenemos el control de navegación clásico de JSF basado en el fichero faces-config.xml y en los valores o outcomes de los actions de los beans de respaldo. Ahora ya no es obligarotio devolver un String en un action, se puede devolver una ruta de navegación en un action o especificarlo en un componente seam: <s:button> o <s:link>.

Para el control de las páginas y la navegación tendremos el fichero pages.xml global, y además, podemos especificar ficheros propios para cada páginas, llamándose el fichero nombrePagina.page.xml

El fichero pages.xml

Este fichero nos permite definir reglas de navegación y otras propiedades de las páginas. Está compuesto por una serie de elementos page, que permiten seleccionar mediante la propiedad view-id una página concreta o un patrón de páginas.

En este fichero podemos también gestionar las excepciones que lance nuestra aplicación para redirigir a pantallas de error concretas.

<?xml version="1.0" encoding="ISO-8859-1"?>
<pages xmlns="http://jboss.com/products/seam/pages"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"
 
       no-conversation-view-id="/paginas/home.xhtml"
       login-view-id="/login.xhtml">
 
    <page view-id="*" >
        <navigation>
            <rule if-outcome="home">
                <redirect view-id="/paginas/home.xhtml"/>
            </rule>
        </navigation>
    </page>
 
    <page view-id="/paginas/*" login-required="true" />
 
    <exception class="org.jboss.seam.framework.EntityNotFoundException">
        <redirect view-id="/paginas/error.xhtml">
            <message severity="warn">#{messages['org.jboss.seam.framework.EntityNotFoundException']}</message>
        </redirect>
    </exception>
 
    <exception class="javax.persistence.EntityNotFoundException">
        <redirect view-id="/paginas/error.xhtml">
            <message severity="warn">#{messages['javax.persistence.EntityNotFoundException']}</message>
        </redirect>
    </exception>
 
    <exception class="javax.persistence.EntityExistsException">
        <redirect view-id="/paginas/error.xhtml">
            <message severity="warn">#{messages['javax.persistence.EntityExistsException']}</message>
        </redirect>
    </exception>
    ...
    ...
</pages>

La etiqueta principal del archivo es <pages> que tiene las siguientes propiedades:

Importante: Cuando ponemos una barra “/” al principio de cualquier ruta que queramos especificar, indica que esa ruta es absoluta al módulo Web. Cuando quiera especificar una ruta relativa, no he de añadir ese carácter al principio de la ruta,

Una vez definida la etiqueta <pages> dentro de ella podemos definir etiquetas <page> que nos permiten definir criterios de navegación según las condiciones que se den en nuestra aplicación. Las propiedades de esta etiqueta son:

Dentro de la etiqueta <page>, podemos definir otras etiquetas que permiten: ejecutar métodos antes de renderizar la página, definir la navegación, gestionar conversaciones, lanzar eventos.

Vamos a ver dichas etiquetas que proporcionan mucha flexibilidad a la hora de crear aplicaciones Web.

La etiqueta navigation puede contener las etiquetas begin-conversation, end-conversation raise-event, redirect, etc. La etiqueta más destacada es rule, que nos permite evaluar lo que se especifica en las propiedades evaluate y from-action. La etiqueta rule tiene las siguientes propiedades:

La etiqueta rule puede contener las etiquetas begin-conversation, end-conversation raise-event, redirect, etc. La más destacada es redirect, que nos permite redirigir la navegación a la página o url que deseemos. La etiqueta redirect tiene las siguientes propiedades:

A continuación mostramos algunos ejemplos de usos de estas etiquetas:

Para la página editDocument.xhtml hemos definido una regla que redirija a viewDocument.xhtml en el caso de que la acción documentEditor.update del bean de respaldo devuelca success

<page view-id="/editDocument.xhtml">
 
    <navigation from-action="#{documentEditor.update}">
        <rule if-outcome="success">
            <redirect view-id="/viewDocument.xhtml"/>
        </rule>
    </navigation>  
</page>

Igual que el anterior, solo que en este caso destruimos la conversación existente al navegar

<page view-id="/editDocument.xhtml">    
    <navigation from-action="#{documentEditor.update}">
        <rule if-outcome="success">
            <end-conversation/>
            <redirect view-id="/viewDocument.xhtml"/>
        </rule>
    </navigation>    
</page>

Redirigimos matando la conversación actual y enviando un parámetro a la página destino

<page view-id="/editDocument.xhtml">
    <navigation from-action="#{documentEditor.update}">
        <rule if="#{documentEditor.errors.empty}">
            <end-conversation/>
            <redirect view-id="/viewDocument.xhtml">
                <param name="documentId" value="#{documentEditor.documentId}"/>
            </redirect>
        </rule>
    </navigation>  
</page>	

El fichero pages.xml tambien nos permite redirigir la navegación cuando se producen excepciones que no pueden ser capturadas. Veamos un ejemplo en el que si se produce la excepción NotLoggedInException, que se produce cuando queremos acceder a una página cuyo acceso esta protegido con autenticación, nos redirige a la página de autenticación (login.xhtml). Además, se añade un mensaje que se muestra en dicha página.

<exception class="org.jboss.seam.security.NotLoggedInException">
    <redirect view-id="/login.xhtml">
        <message severity="warn">#{messages['org.jboss.seam.NotLoggedIn']}</message>
    </redirect>
</exception>

Ficheros page.xml individuales para cada página

El contenido de estos ficheros específicos, se puede incluir dentro del fichero global sin ningún problema, pero se suelen utilizar para encontrar la configuración de las página más rápidamente y para tener un fichero pages.xml más sencillo y comprensible.

Para crear un fichero especifico de control de navegación tenemos que cumplir tres sencillas reglas:

  1. El nombre del fichero tiene que coincidir con con el de la página que configura, es decir, si tenemos una pagina llamada pagina.xhtml, su fichero page.xml específico se llamara pagina.page.xml. Patrón: nombre_pagina.page.xhtml
  2. El fichero tiene que estar en el mismo directorio que la página XHTML.
  3. Debe contener como elemento XML raíz la etiqueta <page>, por esta razón, se puede copiar su contenido en el archivo pages.xml global.
  4. Se puede especificar un fichero de recursos propio mediante la propiedad bundle.

A continuación vemos un ejemplo de fichero específico. La única diferencia con un elemento <page> del fichero global son los espacios de nombres, la definición del esquema, ya que se tratar de un fichero XML y que no se necesita especificar la propiedad viewId, ya que esta implícita en el nombre del archivo.**

<?xml version="1.0" encoding="ISO-8859-1"?>
<page xmlns="http://jboss.com/products/seam/pages"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"
      login-required="true">
 
   <param name="anuncioFrom"/>
   <param name="anuncioId" value="#{anuncioHome.anuncioId}"/>
 
</page>