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

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:

  • no-conversation-view-id: Permite especificar a qué página se navega cuando no se tiene conversación.
  • login-view-id: Permite especificar la página de login de la aplicación.
  • https-port : Permite definir los puertos a utilizar cuando utilicemos SSL.
  • http-port: Permite definir los puertos a utilizar cuando no utilicemos SSL.

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:

  • view-id: Especifica el identificador de la página a configurar, puede ser un patrón como por ejemplo view-id=“*” que especifica todas las páginas del módilo Web, o por ejemplo, view-id=“/paginas/*”, que especifica todas las páginas que se encuentran dentro de la carpeta paginas del modulo WEB.
  • login-required: Indica si para acceder a la página, un usuario tiene que estas autenticado en la aplicación. Puede tener valores true o false.
  • scheme: Permite especificar el esquema de acceso a la página, indicando si se utiliza SSL en la comunicación. Puede tener los valores http o https.
  • no-conversation-view-id: Permite especificar a que página se navega cuando no se tiene conversación.

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.

  • action: Permite ejecutar un método antes de renderizar la página, es útil para realizar comprobaciones o iniciar valores, pero siempre se ejecuta al renderizar la página, es decir, no sólo la primera vez que se pinte, sino también cuando se refresca. Tiene las siguientes propiedades:
    • execute: Indica el método a ejecutar mediante una expresión EL.
    • if: Permite establecer un valor condicional a la ejecución del método mediante una expresión EL.
    • on-postback: Indica si se ejecuta el método durante el postback de la página (postback es la respuesta a una petición HTTP POST).
  • begin-conversation: Indica que se inicie una conversación al renderizar la página. Tiene las siguientes propiedades:
    • flush-mode: Indica la forma de realizar el flush (actualizar la BBDD con los datos de la cache) a hibernate
    • if: Permite establecer un valor condicional a la creación de la conversación, mediante una expresión EL.
    • join: Permite unir la nueva conversación a la conversación actual.
    • conversation: Indica la conversación a la que podemos unirnos (join)
    • nested: Para acceder a la página es obligatorio estar dentro de una conversación.
  • end-conversation: Indica que se cierra la conversación actual. Tiene las siguientes propiedades:
    • before-redirect: Permite especificar si se cierra la conversación antes de la redirección de la navegación.
    • if: Permite establecer un valor condicional a la finalización de la conversación, mediante una expresión EL.
    • root: Permite indicar si se cierra la conversación raíz de la aplicación.
  • description: Permite especificar la descripción textual de la página.
  • restrict: Establece una restricción de acceso a la página especificada en una expresión EL.
  • raise-event: Permite lanzar eventos. Tiene las siguientes propiedades:
    • type: Indicamos el tipo de evento que se lanza. Los eventos se especifican y configuran en el fichero components.xml.
  • param: Permite obtener parámetros del contexto para guardarlos en propiedades de los beans de respaldo, pasarle conversores y validadores. Tiene las siguientes propiedades:
    • name: Indica el nombre de la variable de contexto que contiene el parámetro.
    • value : Indica la propiedad del bean de respaldo donde se guarda el valor del parámetro mediante una expresión EL
    • converter: Indica un conversor de valores mediante una expresión EL, tiene que coincidir con el valor de la anotación @Name en la definición del conversor.
    • converterId: Indica un conversor de valores clasicos de JSF, tiene que estar definido faces-config.xml
    • validator: Indica un validador de valores mediante una expresión EL, tiene que coincidir con el valor de la anotación @Name en la definición del validador o con el método, si se utiliza un método de validación.
    • validatorId: Indica un validador de valores clasicos de JSF, tiene que estar definido faces-config.xml
    • required: Indica si el parámetro es obligatorio, no puede ser nulo.
  • navigation: permite especificar las reglas de navegación a partir de los métodos (actions) del bean de respaldo o EJB. Tiene las siguientes propiedades:
    • from-action: Permite especificar el método sobre el que se evalúa la navegación, si no se utiliza la propiedad evaluate, este método tiene que devolver un valor, y se especifica mediante una expresión EL.
    • evaluate: Permite especificar el valor sobre el que se evalúa la navegación, y se especifica mediante una expresión EL que apunta una propiedad del bean de respaldo.

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:

  • if-outcome: Permite establecer un valor que se compara su igualdad con el valor devuelto por lo especificado en from-action o evaluate.
  • if: Permite establecer un valor condicional para la aceptación de la regla de navegación, mediante una expresión EL.

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:

  • view-id: Permite especificar la página de la aplicación a la que queremos navegar.
  • url: Permite especificar una URL cualquiera.
  • include-page-params: Permite especificar si se incluyen los párametros de la página a la nueva página destino.

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>

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>
  • fdw2.0/fundeweb2.0/gt/control_de_la_navegacion.txt
  • Última modificación: 07/11/2017 10:46
  • (editor externo)