Seam

RECU-0143 (Recurso Referencia)
Tabla de contenidos
  1. 1. Descripción
    1. 1.1. Seam y el mapeo objeto relacional
    2. 1.2. Da soporte a aplicaciones Web con estado
    3. 1.3. Servicios POJOs mediante biyección de dependencias
    4. 1.4. Convención en lugar de configuración
    5. 1.5. El modelo de componentes contextuales
      1. 1.5.1. Contextos Seam
        1. 1.5.1.1. Contexto sin estado (Stateless context)
        2. 1.5.1.2. Contexto de eventos (Even context)
        3. 1.5.1.3. Contexto Página (Page Context)
        4. 1.5.1.4. Contexto de Conversación (Conversation Context)
        5. 1.5.1.5. Contexto de sesión (Session Context)
        6. 1.5.1.6. Contexto de procesos de negocio (Bussines process context)
        7. 1.5.1.7. Contexto de aplicación (Application context)
      2. 1.5.2. Biyección
    6. 1.6. Componentes Seam
      1. 1.6.1. Beans de sesión sin estado (Stateless session beans)
      2. 1.6.2. Beans de sesión con estado (Stateful session beans)
      3. 1.6.3. Beans de entidad (Entity Beans)
      4. 1.6.4. Java Beans
      5. 1.6.5. Message-driven Beans
    7. 1.7. El concepto de la conversación
      1. 1.7.1. El modelo de conversación Seam
      2. 1.7.2. Conversaciones de larga duración
        1. 1.7.2.1. Ciclo de vida de una conversación de larga duración
      3. 1.7.3. Conversación Anidadas
    8. 1.8. Usando caché en Seam
      1. 1.8.1. Cómo se integra la caché
      2. 1.8.2. Almacenamiento de fragmentos de JSF en caché
    9. 1.9. Seguridad
      1. 1.9.1. Autenticación y autorización
      2. 1.9.2. Acceso a los componentes
      3. 1.9.3. Control sobre la identidad y los accesos permitidos de cada usuario
  2. 2. Buenas prácticas y recomendaciones de uso
    1. 2.1. Mejoras recomendadas para la integración con JSF
      1. 2.1.1. ¿Por que Facelets?
      2. 2.1.2. Seam UI Tags
      3. 2.1.3. Mejoras introducidas por Seam en la persistencia de objetos
      4. 2.1.4. Mejoras introducidas por Seam en el lenguaje de expresiones (EL)
      5. 2.1.5. Filtro Seam
  3. 3. Ejemplos
  4. 4. Enlaces externos
  5. 5. Contenidos relacionados

Descripción

Seam se sitúa como la implementación más exitosa sobre Java EE 5.0. Está pensada para proporcionar un modelo de programación coherente y fácil para todos los componentes en una aplicación web de empresa. Seam presenta dos características principales: facilidad de configuración e integración muy elevada de los marcos de referencia de cada capa.

Se elimina la mayor parte del código repetitivo y la configuración de XML a partir de sus aplicaciones. Al resolver el problema de la integración, Seam permite a los desarrolladores web el uso de las herramientas útiles que eran demasiado difíciles de integrar en las aplicaciones Web antes. Por ejemplo, con Seam, es trivial escribir una aplicación web que sea impulsada por los procesos de negocio y las reglas asociadas , o permite escribir una entrada de datos basada en un formulario AJAX que es validado directamente en contra de las limitaciones de bases de datos, o activar los eventos periódicos de forma offline en las aplicaciones web.

Los marcos de referencia fundamentales en Java EE 5.0 son EJB (Enterprise JavaBeans) 3.0 y JSF (JavaServer Faces) 1.2. EJB 3.0 (en lo sucesivo EJB3) convierte Plain Old Java Objects (POJOs) en objetos de servicio de negocio y la persistencia de objetos de bases de datos. JSF es un Model-View-Controller (MVC) framework de componentes para aplicaciones web. La mayoría de aplicaciones web basadas en Java EE 5.0 tienen ambos módulos, EJB3 para la lógica de negocio y módulos JSF de la interfaz web. Sin embargo, a pesar de que EJB3 y JSF son complementarios el uno al otro, están diseñados como marcos separados, cada uno con su propia filosofía.

Por ejemplo, EJB3 utiliza anotaciones para la configuración de servicios, mientras que JSF hace uso de los archivos XML. Por otra parte, EJB3 y los componentes JSF no son conscientes de sí en el nivel del marco. Para hacer trabajar en conjunto a EJB3 y JSF, es necesario una fachada de objetos artificiales (es decir, los beans de respaldo JSF) para vincular los componentes de negocio a las páginas web y código estándar para hacer llamadas a los métodos a través de fronteras del framework .

Integrar ambas tecnologías juntas es parte de las responsabilidades de Seam. Seam ocupa el espacio de la capa artificial entre EJB3 y JSF. Proporciona un consistente enfoque basado en las anotaciones para la integración de EJB3 y JSF. Con unas simples anotaciones, los componentes de negocio EJB3 en Seam se pueden utilizar directamente para respaldar un formulario web JSF o controlar los eventos de la interfaz de usuario web. Seam permite a los desarrolladores utilizar POJOs anotados para todos los componentes de aplicación. En comparación con las aplicaciones desarrolladas con otros frameworks, las aplicaciones desarrolladas en Seam son conceptualmente simples y requieren mucho menos código (en Java y XML) para la misma funcionalidad.

Seam también hace que sea fácil realizar tareas que son difíciles en JSF. Por ejemplo, una de las mayores quejas acerca de JSF es que se basa demasiado en HTTP POST. Es difícil marcar una página web JSF y conseguirlo a través de HTTP GET. En Seam, la generación de una página web es muy sencilla ya que proporciona una serie de etiquetas de componentes JSF y anotaciones que aumentan la "amigabilidad" y la eficiencia de la página web de aplicaciones basadas en JSF.

Seam y el mapeo objeto relacional

Las soluciones ORM se usan para todas las aplicaciones de tipo empresarial. Sin embargo, la mayoría de las aplicaciones no están diseñadas pensando en el mapeo de objetos relacionales. No manejan la persistencia de objetos sobre todo el ciclo de vida de la interacción web, desde el momento de la petición hasta que se ha aplicado la respuesta de forma completa. Esto produce muchos errores en el mapeo relacional, incluido el LazyInitializationException, y requiere de manejo de DTO's para solucionarlo

Seam fue creado por Gavin King, el inventor de la solución más popular de ORM (hibernate), lo que le permite estar diseñado para ejecutar las mejores prácticas en el mapeo relacional. Con Seam no es necesario escribir DTO's. El lazy loading acaba funcionando y el rendimiento del ORM se incrementa gratamente con la extensión del contexto de persistencia, añadiendo cosas como el manejo de una caché natural para reducir las idas y venidas a la base de datos.

Además, puesto que Seam integra la capa del ORM con las capas de negocio y presentación, podemos visualizar los objetos ORM directamente, validar sobre la base de datos, mediante el uso de las anotaciones sobre los formularios de entrada, y redirigir las excepciones ORM a páginas de error por defecto.

Da soporte a aplicaciones Web con estado

Seam ha sido diseñado para aplicaciones Web con estado. Las aplicaciones Web son, de forma inherente, aplicaciones multiusuario, mientras que las aplicaciones de comercio electrónico son aplicaciones con estado y transacciones. Sin embargo, la mayoría de los marcos de aplicaciones Web existentes están dirigidas a aplicaciones sin estado. Lo que obliga a jugar con los objetos de sesión HTTP para manejar estados de usuario. Esto no sólo desordena su aplicación con código que no está relacionado con la lógica de la actividad principal, sino que también trae consigo una serie de problemas de rendimiento.

En Seam, todos los componentes de base de la aplicación son con estado. Son mucho más fáciles de usar que la sesión HTTP, porque Seam gestiona sus estados de forma declarativa. No hay ninguna necesidad de escribir código de gestión de estado en una aplicación de Seam, solamente es necesario anotar el componente con su ámbito de aplicación, los métodos de ciclo de vida, y otras propiedades de estado y Seam se hace cargo del resto. Los componentes con estado también proporcionan un control mucho más fino sobre los estados de usuario que los que la sesión HTTP normalmente proporciona.

Por ejemplo, puede tener múltiples conversaciones, cada una compuesta de una secuencia de peticiones web y de llamadas a métodos de negocio, en una sesión de HTTP. Además, la caché de base de datos y las transacciones pueden ser automáticamente vinculados con el estado de la aplicación mediante Seam. Sostiene automáticamente las actualizaciones de bases de datos en la memoria y se realizan commit a la base de datos sólo al final de una conversación. La caché en memoria reduce en gran medida la carga de base de datos en aplicaciones complejas de estado.

Cada componente con estado en Seam tiene un ámbito o contexto. Por ejemplo, el componente de un carrito de la compra se crea en el inicio de una conversación de compras y se destruye al final de la conversación cuando todos los artículos están desprotegidos. Por lo tanto, este componente vive en el contexto de una conversación. Su aplicación simplemente declara este contexto a través de anotaciones en el componente, y Seam gestiona automáticamente el componente, la creación del mismo, el estado, y eliminación.

Seam proporciona varios niveles de contextos con estado, que van desde una solicitud única a la Web a una conversación de varias páginas, una sesión de HTTP, o un largo proceso de negocio en funcionamiento

Servicios POJOs mediante biyección de dependencias

Seam es un framework de peso ligero, ya que promueve el uso de Plain Old Java Objects (POJOs) como componentes de servicio. En el framework no existen interfaces o clases abstractas para enganchar componentes en la aplicación. La pregunta, por supuesto, es ¿cómo los POJOs interactúan unos con otros para formar una aplicación? ¿Cómo interactúan con el envase de servicios (por ejemplo, el servicio de persistencia de bases de datos)?

Seam conecta los componentes POJO, mediante un patrón de diseño popular conocido como la dependencia de inyección (DI). Bajo este esquema, el framework gestiona el ciclo de vida de todos los componentes. Cuando un componente tiene que usar otro, se declara esta dependencia en Seam, mediante anotaciones. Seam determina dónde conseguir este componente dependiente basándose en el estado actual de la aplicación y lo "inyecta" en el componente que ha realizado la petición.

Amplia el concepto de inyección de dependencias, un componente de Seam A también puede crear otro componente B, y devolviendo el componente B creado de nuevo a Seam para que otros componentes, tales como C, lo usen posteriormente.

Este tipo de gestión de la dependencia bidireccional es ampliamente utilizado en las más sencillas Aplicaciones web . Es lo que llamamos biyección de dependencias.

Convención en lugar de configuración

El principio clave de diseño que hace Seam tan fácil de usar es el Convenio sobre la configuración, también llamado de configuración por excepción. La idea es tener un conjunto de los comportamientos predeterminados de sentido común para los componentes (es decir, la Convención). El desarrollador necesita configurar el componente explícitamente sólo cuando la conducta deseada no es el valor predeterminado. Por ejemplo, cuando se inyecta el nombre Seam del componente A como una propiedad del componente B, el nombre del componente A es por defecto el nombre de la propiedad (propierty) receptora en el  componente B.

Muchas cosas como estas se cumplen en Seam. En general, la configuración de metadatos en Seam es mucho más simple que en los marcos de la competencia de Java. Como resultado, la mayoría de las aplicaciones pueden ser adecuadamente configuradas con un pequeño número de simples anotaciones Java. Los desarrolladores se benefician de la reducción de la complejidad y, al final, menos líneas de código para la misma funcionalidad en comparación con los marcos de la competencia.

El modelo de componentes contextuales

Los dos conceptos básicos en Seam son los conceptos de un contexto y la noción de un componente. Los componentes son objetos con estado, por lo general EJBs, y una instancia de un componente se asocia con un contexto, y se le da un nombre en ese contexto. La biyección proporciona un mecanismo para asignar alias a nombres de los componentes internos (variables de instancia) para asignarlos a los nombres de contexto, lo que permite que los árboles de componentes sean montados de forma dinámica, y remontados por Seam.

Contextos Seam

Los contextos Seam se crean y se destruyen por el marco. La aplicación no controla de forma explicita la demarcación de los contextos. Los contextos son normalmente implícitos, aunque en algunas situaciones pueden demarcarse mediante anotaciones. Los contextos básicos de Seam son:

  • Stateless context
  • Event (i.e., request) context
  • Page context
  • Conversation context
  • Session context
  • Business process context
  • Application context

Se reconocen algunos de estos contextos por los de servlets y especificaciones relacionadas. Sin embargo, dos de ellos deben de ser nuevos: Contexto de conversación (Conversation context) y el contexto de proceso de negocio (bussines process context). Una de las razones por las que el manejo del estado en las aplicaciones web es tan frágil es porque se construye en tres contextos diferentes (request, session y application) y no son especialmente comprensibles desde el punto de vista de la lógica de negocio. Una sesión de inicio de sesión de usuario, por ejemplo, es una construcción bastante arbitraria en términos de la aplicación real del flujo de trabajo. Por lo tanto, la mayoría de los componentes de Seam están en el ámbito de la conversación o contextos de procesos de negocio, ya que son los contextos que son más significativos en términos de la solicitud.

Contexto sin estado (Stateless context)

Los componentes que no tienen estado (stateless session beans, principalmente) siempre viven en este contexto (que es básicamente la ausencia de un contexto desde el cual la instancia Seam resuelta no se almacena). Los componentes sin estado no son muy interesantes y no son muy orientados a objetos. Sin embargo son desarrollados y usados, por lo que son parte importante de cualquier desarrollo en Seam.

Contexto de eventos (Even context)

Es el más cercano al contexto con estado, y es una generalización de la noción del contexto de la petición Web para cubrir otro tipo de eventos. Sin embargo, el contexto de eventos asociado con el ciclo de vida de la petición JSF es el ejemplo más importante de este tipo de contexto y uno con los que trabajará más a menudo. Los componentes asociados con el contexto de evento son destruidos al final de una petición, pero su estado es accesible y bien definido hasta el final del ciclo de vida de la petición.

Contexto Página (Page Context)

El contexto de página permite asociar un estado con una instancia particular de una página reproducida. Puede inicializar el estado en el detector de eventos (event listener), o mientras actualiza el renderizado de la página y teniendo acceso a cualquier evento originario de esa página. Esto es especialmente útil para la funcionalidad como listas de hacer clic, donde cuenta con el respaldo de la lista de modificaciones a los datos en el servidor. El estado, en realidad, se serializa en el cliente, por lo que esta construcción es extremadamente robusta con respecto a la operación multi-ventana y el botón Atrás.

Contexto de Conversación (Conversation Context)

El contexto de la conversación es un concepto central en Seam. Una conversación es una unidad de trabajo desde el punto de vista del usuario. Podría agrupar varias interacciones con el usuario, varias solicitudes, y varias transacciones de bases de datos. Pero, para el usuario, una conversación resuelve un solo problema. Puede entenderse que una conversación es como "un caso de uso" pero la relación no es totalmente exacta.

Una conversación mantiene el estado asociado con "lo que el usuario está haciendo ahora, en esta ventana". Un solo usuario puede tener múltiples conversaciones en curso en cualquier momento, por lo general,  en varias ventanas. El contexto de la conversación nos permite garantizar que el estado de las conversaciones diferentes no chocan entre sí y provocan errores.

Algunas conversaciones duran tan sólo una única solicitud. Otras conversaciones, que abarcan múltiples solicitudes, se delimitarán mediante anotaciones proporcionada por Seam. Algunas conversaciones son también tareas. Una tarea es una conversación que es significativa en términos de procesos de negocio, y tiene el potencial de desencadenar un proceso de negocio de transición de estados cuando es completado con éxito. Seam proporciona un conjunto especial de anotaciones para la demarcación de tareas.

Las conversaciones se pueden anidar, con una conversación que tenía lugar "dentro" de una conversación más amplia. Ésta es una característica avanzada. Por lo general, el estado de conversación es mantenido por Seam en la sesión servlet entre peticiones. Seam implementa un timeout configurable para la conversación, destruyendo automáticamente conversaciones inactivas, asegurando que el estado en poder de una sesión de usuario logado no crece sin límite si el usuario abandona las conversaciones.

Seam serializa el procesamiento de solicitudes simultáneas que se realizan en el mismo contexto de conversación, en el mismo proceso. Por otra parte, se puede configurar para mantener el estado de conversación en el navegador del cliente.

Contexto de sesión (Session Context)

Un contexto de sesión mantiene asociado el estado con la sesión del usuario logado. Mientras hay algunos casos donde es útil compartir el estado entre varias conversaciones, generalmente utilizamos el contexto de sesión para mantener componentes más que información global sobre el usuario logado.

Contexto de procesos de negocio (Bussines process context)

El contexto del proceso de negocio mantiene el estado asociado con el proceso de negocio. Este estado es manejado y hecho persistente por el motor BPM (JBoss jBPM). El contexto de proceso de negocio agrupa múltiples interacciones con múltiples usuarios, compartiendo el estado entre múltiples usuarios pero en una manera bien definida.

La tarea actual determina que la instancia actual de proceso de negocio, y el ciclo de vida del proceso de negocio es definido externamente usando un lenguaje de definición de procesos, así que no son necesarias anotaciones especiales para la demarcación del proceso de negocio.

Contexto de aplicación (Application context)

El contexto de aplicación es familiar por el contexto servlet y por la especificación servlet. El contexto de aplicación es útil para mantener información estática como la configuración de datos, datos de referencia o metamodelos. Por ejemplo, Seam almacena su propia configuración y metamodelo en el contexto de aplicación.

Biyección

La inyección de dependencia es un concepto familiar para la mayoría de los desarrolladores de Java. Permite a un componente obtener una referencia a otro componente para "inyectar" el contenedor sobre el otro componente mediante un método setter o una variable de instancia. En todas los implementaciones de inyección de dependencia que hemos visto, la inyección se produce cuando el componente se construye, y la referencia no cambia posteriormente durante la vida útil de la instancia del componente.

Esto resulta razonable para los componentes sin estado. Desde el punto de vista de un cliente, todas las instancias de un componente particular sin estado son intercambiables. Por otra parte, Seam hace hincapié en la utilización de componentes con estado. Para estos componentes ya no es útil construir la inyección de dependencias tradicional. Seam introduce la noción de biyección como una generalización de la inyección para solucionar esta problemática y agrupa a dos mecanismos: injection y outjection

El mecanismo de inyección (injection) permite a un componente A obtener de un contexto una referencia a una instancia de un componente B, haciendo que el contenedor de aplicaciones ”inyecte” el componente B en una variable del componente A. El mecanismo de outjection permite que un componente B esté disponible en un contexto para poder ser inyectado en un componente A. Es decir, mediante outjection se toma una instancia de un componente y se deposita en un contexto, y mediante injection se toma una instancia de un componente de un contexto y se asocia a una variable de otro componente.

A diferencia de la inyección, biyección es:

  • Contextual: La biyección se utiliza para ensamblar los componentes con estado de diversos contextos diferentes.
  • Bidireccional: Los valores son inyectados a partir de las variables del contexto en atributos del componente que se está invocado, y también desde los atributos del componente regresan al contexto (outject), lo que permite al componente que se invoca manipular los valores de las variables contextuales simplemente estableciendo sus propias variables instancia.
  • Dinámica: Ya que el valor de las variables contextuales cambia con el tiempo, y en los componentes con estado de Seam, la biyección se lleva a cabo cada vez que se invoca un componente.

En esencia, la biyección crea una relación entre una variable de contexto y una variable de instancia de componente, porque se especifica que el valor de la variable de instancia se inyecta, se extrae, o ambas cosas. Por supuesto, utilizamos anotaciones para indicar la biyección.

La anotación @In es para inyectar componentes de la aplicación en el componente actual. La anotación @In puede recibir valores:

  • create = true/false que indica si se crea el componente en caso de que no exista (o lo que es lo mismo en caso de que Seam no lo haya creado en una petición anterior).
  • required = true/false indicando si el componente debe estar creado con anterioridad, en caso de que no exista la aplicación, fallaría y debería lanzarse una excepción.
  • y los relacionados con el scope y el value que son el ámbito y el nombre del componente.
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@In User user;
...
}

o dentro de un método set

@Name("loginAction")
@Stateless
public class LoginAction implements Login {
  User user;
  @In
  public void setUser(User user) {
     this.user=user;
  }
  ...
}

De forma predeterminada, Seam hace una búsqueda prioritaria de todos los contextos, utilizando el nombre de la propiedad o la variable que está siendo inyectada. Es posible que desee especificar el nombre de variable de contexto de forma explícita, utilizando, por ejemplo, @In ("CurrentUser"). Puede inyectar expresiones como el siguiente ejemplo:

@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@In("#{user.username}") String username;
...
}
 

La anotación @Out es para "outyectar" componentes, o dicho de otra forma inyectar hacia fuera, y de ahí el término biyección que utiliza Seam. La anotación @Out puede recibir valores:

  • required = true/false.
  • scope = relacionado con el ámbito.
  • value = relaciona con el nombre del contexto.
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@Out User user;
...

}

Componentes Seam

Los componentes Seam son POJOs. En particular, son JavaBeans o EJB3 Enterprise JavaBeans. Seam fue diseñado con EJB3 e incluye una profunda integración con él. Soporta los siguientes tipos de componentes:

  • EJB 3.0 stateless session beans
  • EJB 3.0 stateful session beans
  • EJB 3.0 entity beans (i.e., JPA entity classes)
  • JavaBeans
  • EJB 3.0 message-driven beans

Beans de sesión sin estado (Stateless session beans)

Los componente no están disponibles para mantener el estado a través de múltiples llamadas. Sin embargo, se usan habitualmente para operar con el estado de otros componentes en varios contextos Seam. Se usan como detectores de acción de JSF (action listener), pero no pueden proveer de las propiedades de los componentes para mostrar. Este componente siempre vive en el contexto sin estado (staless context)

Los beans de sesión sin estado pueden ser accedidos de forma concurrente por cada nueva instancia que se use por cada petición. Asignar la instancia a la petición es responsabilidad del contenedor de EJB3.

Beans de sesión con estado (Stateful session beans)

Pueden mantener el estado no solo a través de múltiples invocaciones del bean, sino también a través de múltiples peticiones. El estado de la aplicación no se mantiene en la base de datos como usualmente lo realizan los beans de sesión con estado en otros frameworks. Ésta es la gran diferencia de Seam con ellos.

En lugar de pegar información sobre la conversación actual directamente en la HttpSession, se pueden mantener, en la instancia, variables del bean de sesión con estado que pertenece al contexto de la conversación. Esto permite a Seam manejar el ciclo de vida del estado, asegurando que no existen conflictos entre los estados relacionados de diferentes conversaciones.

Los beans de sesión con estado son utilizados habitualmente como detectores de acción en JSF, y como un bean de respaldo que provee de propiedades a los componentes de JSF para mostrar o completar los formularios. Por defecto, estan vinculados al contexto de conversación. Nunca aparecen en los contextos de página o sin estado. Las peticiones concurrentes en el ámbito de sesión de los beans de sesión con estado son siempre serializadas por Seam siempre y cuando los interceptores de Seam no estén desactivados para el bean. Los beans de sesión de estado pueden instanciarse en Seam usando la anotación @In(create=true).

Beans de entidad (Entity Beans)

Los beans de entidad pueden estar ligado a una variable de contexto y funcionan como componente de Seam. Como las entidades tienen una identidad persistente, además de su identidad contextual, las instancias por lo general están vinculadas de manera explícita en el código de Java, en lugar de ser una instancia implícitamente en Seam.

Los componentes beans de entidad no admiten biyección o demarcación de contexto. Tampoco admiten la invocación de un bean de entidad de activación como validación. Los beans de entidad no son usados como detectores de acción en JSF, pero a menudo ofrecen otras funciones como beans de respaldo para proveer de información a los componentes JSF. En particular, es habitual usarlos como un bean de respaldo, junto a un bean de sesión con estado que actúe de detector para implementar la creación/actualización/borrado de tipos de funcionalidad. Por defecto, las entidades están vinculadas al contexto de la conversación. Nunca aparecen en el contexto sin estado.

Java Beans

Pueden usarse como un bean con o sin estado. Sin embargo, no proveen de funcionalidad al bean de sesión (demarcación de la transacción declarativa, seguridad declarativa, persistencia EJB3, métodos de timeout ,etc). Cuando se utilice Seam sin un contenedor EJB, los componentes serán JavaBeans en lugar de beans de sesión. Sin embargo, hay muchos servidores de aplicaciones que son menos eficientes si se agrupa el ámbito Seam de sesión o de conversación. Por defecto, JavaBeans aparecen en el contexto de eventos. Las peticiones concurrentes en el ámbito de sesión de los JavaBeans son serializados por Seam

Message-driven Beans

Pueden funcionar como un componente de Seam. Sin embargo, los beans controlados por mensajes se denominan de manera muy diferente a otros componentes de Seam (en lugar de invocarse a través de ellos el contexto variable, escuchan los mensajes enviados a una cola).

Los beans por mensajes no estarán vinculados a un contexto Seam. Tampoco tienen acceso a la sesión o al estado de la conversación de sus "llamantes". Sin embargo, sí soportan la biyección y algunas otras funcionalidades de Seam. Nunca son instanciados por la aplicación. Son instanciados por el contenedor EJB cuando se recibe un mensaje.

El concepto de la conversación

Históricamente, la noción de una "conversación" surgió como una fusión de tres conceptos diferentes:

• La idea de un espacio de trabajo, • La idea de una aplicación con transacciones con la semántica optimista, y la realidad de que los actuales marcos en torno a una arquitectura sin estado no pueden proporcionar una gestión eficaz del manejo de la persistencia. • La idea de un flujo de trabajo de tareas.

Al unificar estas ideas, y con el apoyo del framework, tenemos una poderosa construcción que nos permite construir aplicaciones más ricas y más eficientes con menos código que antes.

El modelo de conversación Seam

Los ejemplos que hemos visto hasta ahora hacen uso de un modelo muy simple de conversación que sigue estas reglas:

  • Siempre hay un contexto conversación activo durante la petición, se aplican los valores al proceso de validaciones, se actualizan los valores del modelo, se invoca la aplicación y se reproduce la respuesta durante las fases de ciclo de vida de la petición JSF.
  • Al final de la restauración del ciclo de vida de JSF, Seam intenta restaurar cualquier contexto de conversación a largo plazo (long-running). Si no existen, Seam crea un contexto nuevo de conversación temporal.
  • Cuando se encuentra una anotación @Begin, el contexto temporal promociona a conversación a largo plazo.
  • Cuando se encuentra una anotación @End, el contexto de conversación a largo plazo es degradado a contexto de conversación temporal
  • Cualquier petición de una vista propaga el contexto de la conversación. Por defecto, peticiones no faces (peticiones Get por ejemplo) no propagan el contexto de la conversación.
  • Si el ciclo de vida de la petición JSF es forzado por una redirección, Seam almacena transparentemente y restablece el contexto de conversación actual, a menos que se haya finalizado la conversación mediante la anotación @End(beforeRedirect=true).

Seam propaga de forma transparente el contexto de la conversación (incluyendo la conversación temporal) a través de las redirecciones y vueltas atrás de JSF. Si no se hace nada especial, una petición no faces, no propaga el contexto de la conversación y serán procesados en una nueva conversación temporal. Si realmente quiere propagarse el contexto hay que especificarlo explícitamente en el código

La etiqueta <s:conversationPropagation> pueden usarse para iniciar y finalizar la conversación, o para comenzar una conversación anidada.

<h:commandLink action="main" value="Exit">
<s:conversationPropagation type="end"/>
</h:commandLink>

Este modelo de conversación hace que sea fácil crear aplicaciones que se comportan correctamente con respecto al manejo de múltiples ventanas. Para muchas aplicaciones, esto es todo lo que se necesita. Algunos aplicaciones más complejas tienen uno o ambos de los siguientes requisitos adicionales:

  • Una conversación se extiende por muchas unidades más pequeñas de interacción del usuario, que se ejecutan en serie o incluso al mismo tiempo. Las conversaciones más pequeñas anidadas tienen su propio conjunto de conversación con su estado aislado, y también tienen acceso al estado de la conversación exterior.
  • El usuario puede cambiar entre muchas conversaciones dentro de la misma ventana del navegador. Esta función se denomina gestión de espacio de trabajo.

Conversaciones de larga duración

En una aplicación Web, una conversación de larga duración, por lo general, consiste de una serie de páginas web que el usuario debe seguir para realizar una tarea. Los datos generados por la aplicación, a partir de la tarea, son persistentes para la base de datos al final de la conversación. Por ejemplo, en una aplicación de comercio electrónico, el proceso de pago es una conversación, que consiste en una página de confirmación del pedido, una página para la información de la facturación, y una última página para el código de confirmación.

Ciclo de vida de una conversación de larga duración

El ciclo de vida de una conversación puede parecer complejo al principio pero, en realidad, es bastante simple. Una conversación tiene esencialmente dos estados principales, temporal y de larga duración. Una conversación temporal se inicia con cada solicitud a menos que una conversación de larga duración anterior se reanude.

Esto significa que, incluso si en su aplicación no se especifica explícitamente el manejo de conversación, una conversación se inicializa para cada solicitud. El ciclo vida de una conversación temporal es una sola solicitud, sin embargo, una conversación temporal asciende a larga si se especifica a Seam que va a comenzar una conversación de larga duración. Una forma sencilla de hacerlo es anotando un método de acción con @Begin. Mediante la promoción de una conversación de larga duración, se le dice a Seam que queremos que la conversación se mantenga entre las solicitudes. Por lo tanto, nuestra conversación y todas las variables a mantener en su estado serán registradas por Seam una vez que la petición se complete. Esta conversación, puede retomarse en las solicitudes posteriores.

Conversación Anidadas

Una conversación anidada se crea al invocar un método marcado con la anotación @Begin (nested = true) en el interior del alcance de una conversación existente. Una conversación anidada tiene su propio contexto de conversación, pero puede leer los valores del contexto exterior de la conversación. El contexto exterior de la conversación es de sólo lectura dentro de una conversación anidada, ya que los objetos se obtienen por referencia y si se produjeran los cambios en los mismos objetos se reflejarían en el contexto exterior.

  • Anidar una conversación a través de inicializar el contexto en el que se apila el contexto de la conversación original. La conversación original es la considerada padre.
  • Todos los valores outjected o directamente puestos en el contexto de la conversación anidada no afectan a los objetos accesibles en el contexto de la conversación de sus padres.
  • La inyección o una búsqueda de contexto a partir del contexto de conversación busca el valor, primero, en el contexto de conversación en curso y, si no se encuentra ningún valor, seguirá por la conversación de pila si la conversación se anida. Como se verá, este comportamiento puede ser anulado.

Cuando se encuentra una etiqueta @End, la conversación anidada será destruida, y la conversación externa se reanudará, por el "estallido" de la pila de conversaciones. Se puede establecer un grado de anidamiento de forma arbitraria. La conversación del fondo de la pila es considerada la conversación raíz.. Si se destruye esta conversación, se destruyen todos sus descendientes.

Usando caché en Seam

En casi todas las aplicaciones empresariales, la base de datos es el cuello de botella principal, y el que produce menor nivel de escalabilidad del entorno de ejecución. Casi todo lo que podamos hacer para compartir la base de datos con menos frecuencia vale la pena hacerlo. Esto exige una caché. Bueno, no sólo una memoria caché. Una aplicación bien diseñada en Seam contará con una estrategia, el almacenamiento en caché de varias capas que afecta a todas las capas de la aplicación:

  • La base de datos, por supuesto, tiene su propia caché. Esto es súper importante, pero no se puede escalar como una caché en el nivel de aplicación.
  • Su solución ORM (Hibernate, o alguna otra aplicación) tiene una memoria caché de segundo nivel de datos de la base de datos. Ésta es una capacidad muy poderosa, pero a menudo se abusa demasiado de ella. En un entorno agrupado, mantener los datos en la caché transaccional coherente en todo el grupo, y con la base de datos, es bastante caro. Tiene más sentido realizarlo para los datos que se comparten entre muchos usuarios, y que rara vez se actualizan. En las arquitecturas tradicionales sin estado, las personas a menudo tratan de utilizar la caché de segundo nivel para el estado de conversación. Esto siempre es malo, y es especialmente malo en Seam.
  • El contexto de la conversación Seam es una caché de estados de conversación. Los componentes que usted pone en el contexto de la conversación puede contener y cachear el estado relacionado con la interacción del usuario actual.
  • En particular, el contexto de persistencia gestionado por Seam actúa como una caché de datos que se han leído en la conversación actual. Esta caché tiende a tener un hit-rate bastante alto. Seam optimiza el manejo de los contextos de persistencia con un entorno cluster. Y no existe un requisito de coherencia transaccional con la base de datos (el bloqueo optimista es suficiente) por lo que no tiene que preocuparse demasiado acerca de las implicaciones de rendimiento de esta caché, a menos que se hayan leído miles de objetos en un contexto de persistencia único.
  • La aplicación puede almacenar en caché el estado no transaccional en el contexto de aplicación de Seam. El estado mantenido en el contexto de aplicación no es visible a otros nodos del clúster.
  • Seam permite que se cacheen fragmentos de páginas de JSF. A diferencia de la memoria caché de segundo nivel ORM, esta caché no es automáticamente invalidada cuando cambian los datos, por lo que necesita escribir código para realizar la anulación explícita en la aplicación, o un conjunto de políticas adecuadas de caducidad.

El proveedor de caché (CacheProvider) dispone de una API que contiene los siguientes métodos que pueden referenciarse por anotaciones como cualquier componente Seam.

MétodoDescripción
put(String region, String key, Object object)Aloja un objeto en caché dándole una clave y una región
get(String region, String key)Deuvelve un objeto de la caché con una región y una clave asociada
remove(String region, String key)Elimina el objeto de caché

Y aquí un ejemplo de uso:

@Name("chatroomUsers")
@Scope(ScopeType.STATELESS)
public class ChatroomUsers

{
    @In CacheProvider cacheProvider;
    @Unwrap
    public Set<String> getUsers() throws CacheException   {
        Set<String> userList = (Set<String>) cacheProvider.get("chatroom", "userList");
        if (userList==null) {
            userList = new HashSet<String>();
            cacheProvider.put("chatroom", "userList", userList);
        }
        return userList;
    }
}

Cómo se integra la caché

Seam hace que sea sencillo lograr un aumento del rendimiento mediante la integración con un proveedor de caché . Hay tres proveedores de caché con el soporte en Seam: JBoss Cache, Boss POJO Cache y EHCache. Es necesario configurarlo en el fichero de configuración (Treecache.xml en el caso del Jboss Cache y ehcache.xml, en el caso de usar EHcache) y declararlo en el fichero de componentes components.xml:

<components xmlns="http://jboss.com/products/seam/components"
            xmlns:cache="http://jboss.com/products/seam/cache">
   <cache:jboss-cache-provider configuration="META-INF/cache/treecache.xml" />
</components>

El componente integrado PojoCache maneja una instancia de org.jboss.cache.aop.PojoCache. Puede poner, de forma segura, cualquier objeto inmutable en la caché de Java, y será replicado en todo el clúster (suponiendo que la replicación está habilitada). Si desea conservar los objetos mutables en el caché, tendrá que ejecutar el preprocesador bytecode JBossCache para garantizar que los cambios en los objetos se detectan automáticamente y se replican.

Para utilizar PojoCache, todo lo que necesitas hacer es poner los jars de JBossCache en el classpath, y proporcionar un recurso denominado treecache.xml con una configuración de la caché correspondiente. Ahora ya puede inyectar el caché en cualquier componente de Seam

@Name("chatroom")
public class Chatroom {
    @In PojoCache pojoCache;
   
    public void join(String username) {
      try
      {
         Set<String> userList = (Set<String>) pojoCache.get("chatroom", "userList");
         if (userList==null)
         {
            userList = new HashSet<String>();
            pojoCache.put("chatroom", "userList", userList);
         }
         userList.put(username);
      }
      catch (CacheException ce)
      {
         throw new RuntimeException(ce);
      }
    }
}

Almacenamiento de fragmentos de JSF en caché

El uso más interesante es el almacenamiento de fragmentos de JSF en caché, para ello se hace uso de la etiqueta <s:cache>, que es la solución de Seam para el problema de la caché fragmentada en la página JSF. La etiqueta utiliza internamente PojoCache, por lo que se necesita para seguir los pasos anteriores antes de poder usarlo.

<s:cache> se utiliza para almacenar en caché el contenido representado parcialmente que en raras ocasiones cambia. Por ejemplo, la página de bienvenida de nuestro blog muestra las entradas de blog recientes:

<s:cache key="recentEntries-#{blog.id}" region="welcomePageFragments">
   <h:dataTable value="#{blog.recentEntries}" var="blogEntry">
      <h:column>
         <h3>#{blogEntry.title}</h3>
         <div>
            <s:formattedText value="#{blogEntry.body}"/>
         </div>
      </h:column>
   </h:dataTable>
</s:cache>

Seguridad

El aspecto más importante de un marco de seguridad es la autenticación de usuario. Cada usuario debe identificarse con un nombre de usuario y contraseña combinado para acceder a las zonas restringidas de las aplicaciones Web. Estos nombres de usuario y contraseñas se comprueban en contra de alguna fuente de autenticación (por ejemplo, LDAP, la fuente de datos, etc) para verificar que el usuario es quien él o ella dice ser. Una vez verificada la identidad del usuario, podemos determinar el rol del usuario dentro de la solicitud. Cada usuario puede tener una o varias funciones de seguridad, y tener autorización para ingresar a ciertas secciones restringidas o características de la aplicación.

Autenticación y autorización

Seam se basa en el estándar JAAS (Servicio Java de autenticación y autorización). También ofrece un enfoque simplificado para la autenticación y autorización que le permite incorporar rápidamente la seguridad en su aplicación. Primero, hay que escribir un formulario de acceso para el usuario introduzca nombre de usuario y contraseña. En el formulario de acceso, debe obligar a hacer un binding de las credenciales de usuario incorporado en #credentials de los componentes. El componente #identity se puede invocar para autenticar al usuario basado en las credenciales proporcionadas.

<div>
  Username:
  <h:inputText value="#{credentials.username}"/>
</div>
<div>
  Password:
  <h:inputSecret value="#{credentials.password}"/>
</div>
<div>
  <h:commandButton value="Account Login"
  action="#{identity.login}"/>
</div>

Ambos componentes se encuentran en el ambito de HttpSession. Una vez el usuario esta logado, se mantiene logado hasta que la sesión expire por lo que el método #{identity.login} se convierte en un método que llama a un autenticador. El método llamado debe asegurar que la instancia de credenciales del usuario y la contraseña "inyectada" son válidas. Opcionalmente, el método podrá informar acerca de los roles asociado al usuario, añadiendo roles al mismo. Un ejemplo de un metodo autenticador es el siguiente:

@Stateless
@Name("authenticator")
public class AuthenticatorAction implements Authenticator {
  @In EntityManager em;
  @In Credentials credentials;
  @In Identity identity;
  @Out(required=false, scope = SESSION)
  private User user;
  public boolean authenticate()
  {
    List results = em.createQuery( "select u from User u where u.username=#{credentials.username}" + " and u.password=#{credentials.password}").getResultList();
    if ( results.size()==0 )
    {
      return false;
    }
    else
    {
      user = (User) results.get(0);
      for(Role role : user.getRoles())
      {
         identity.addRole(role.getRolename());
      }
     return true;
    }
  }
}

Acceso a los componentes

El control de acceso en la interfaz de usuario es simple de entender, pero no es suficiente. Es importante asegurar los componentes y los respectivos métodos de Java en la aplicación. Afortunadamente, es fácil declarar componentes y restricciones de nivel de acceso mediante anotaciones y expresiones EL

@Stateful
@Scope(EVENT)
@Name("changePassword")
public class ChangePasswordAction implements ChangePassword
{
   @Restrict("#{identity.loggedIn}")
   public void changePassword()
   {
      if ( user.getPassword().equals(verify) )
      {
         user = em.merge(user);
         facesMessages.add("Password updated");
         changed = true;
      }
      else
      {
         facesMessages.addToControl("verify", "Re-enter new password");
         revertUser();
         verify = null;
      }
   }
}

Control sobre la identidad y los accesos permitidos de cada usuario

Seam proporciona una API que permite el manejo de la identidad del usuario y los roles. El IdentityManager proporciona soporte para las siguientes cuestiones:

  • Autenticación contra la configuración de almacenamiento de identidades.
  • Operaciones CRUD (crear, leer, actualizar y eliminar) para los usuarios y roles.
  • La concesión y revocación de funciones, cambiar contraseñas, activar y desactivar el usuario cuentas, el listado de usuarios y roles, etc.

El componente IdentityStore interactúa con el proveedor. Sólo necesita configurar apropiadamente la instancia de IdentityStore para ser inyectada en el manejador IdentityManager en tiempo de ejecución. Puede crear un proveedor que implemente la interfaz IdentityStore y configurarlo para la inyección. Seam hace uso de las anotaciones para manejar la identidad de los usuarios, a continuación en una tabla se resumen las más importantes.

AnotaciónUsoEntidadDescripción
@UserPrincipalCampo, métodouser entityEsta anotación delimita el campo o método que contiene el nombre de usuario
@UserPasswordCampo, Métodouser entityEsta anotación delimita el campo o método que contiene la contraseña del usuario
@UserrolesCampo, Métodouser entityEsta anotación delimita el campo o método que contiene los roles del usuario
@RolenameCampo, Métodorole entityEsta anotación delimita el campo o método que contiene el nombre del rol del usuario

Y un ejemplo de uso:

@Entity
@Name("user")
@Scope(SESSION)
@Table(name="Customer")
  public class User implements Serializable
  {
    private String username;
    private String password;
    private List<Role> roles;
    // ... ...
    @UserPrincipal
    @Id
    @Length(min=5, max=15)
    @Pattern(regex="^\\w*$", message="not a valid username")
  public String getUsername()
  {
    return username;
  }
  public void setUsername(String username)
  {
    this.username = username;
  }
  @UserRoles
  @ManyToMany(fetch=FetchType.EAGER)
  @JoinTable(joinColumns={ @JoinColumn(name="USERNAME") },
   inverseJoinColumns={ @JoinColumn(name="ID")
   }
  )
  public List<Role> getRoles()
  {
    return roles;
  }
  public void setRoles(List<Role> roles)
  {
   this.roles = roles;
  }

Buenas prácticas y recomendaciones de uso

Mejoras recomendadas para la integración con JSF

Seam elige JSF como framework de desarrollo web por muchas razones. JSF es una tecnología estándar en Java EE 5.0 y tiene un gran ecosistema de los usuarios y los vendedores. Todos los servidores de aplicaciones Java apoyan la especificación. JSF está totalmente basado en componentes y existe una importante comunidad de proveedores de componentes. JSF también dispone de un lenguaje potente y unificado de expresión lingüística (EL, usando la notación #{...}) que se puede utilizar en páginas web, descripciones de flujo de trabajo, y en los archivos de configuración de los componentes en toda la aplicación.

JSF también goza de gran apoyo por parte visual en las principales herramientas de la GUI de IDEs de Java. Sin embargo, JSF también tiene su cuota de problemas. Ha sido criticado por ser demasiado detallado y demasiado centrado en los componentes (es decir, no es transparente a las peticiones HTTP). Al ser un marco normativo, JSF innova más lentamente que los proyectos de código abierto tales como Seam en sí mismo y por lo tanto menos ágil a la hora de corregir cuestiones e ir añadiendo nuevas características.

Por estas razones, Seam trabaja con otros proyectos de código abierto para mejorar y realzar JSF. Para las aplicaciones de Seam, se utilizan las siguientes mejoras en su interacción con JSF:

  • El marco Facelets para páginas web. Se escriben las páginas web como archivos XHTML en Facelets en lugar de los archivos JSP. Facelets proporciona muchas ventajas sobre el estándar JSP en JSF
  • Se utiliza la biblioteca de componentes JSF de Seam, especialmente las etiquetas JSF que se aprovechan de características específicas de Seam.
  • Se establecen los filtros Seam para capturar y gestionar JSF (redirecciones, mensajes de error, la depuración información, y así sucesivamente).

¿Por que Facelets?

En primer lugar, mejora el rendimiento JSF un 30 y un 50 por ciento dejar el motor JSP y utilizar páginas XHTML directamente como la tecnología de visión. Al evitar JSP, Facelets también evita posibles conflictos entre la especificación JSF 1.1 y JSP 2.4 , que son las especificaciones compatibles con JBoss AS 4.x.

En segundo lugar, puede utilizar las etiquetas XHTML en páginas Facelets. Elimina la necesidad de adjuntar etiquetas XHTML y texto libre en las etiquetas <f:verbatim>. Estas etiquetas <f:verbatim> aumentan la complejidad y disminuyen la legibilidad de las páginas JSF basadas en JSP

En tercer lugar, Facelets proporciona soporte de depuración desde el navegador. Si se produce un error cuando utiliza Facelets en una página, te da la ubicación exacta de este error en el archivo de código fuente y proporciona información de contexto alrededor del error.

Por último, y quizás lo más importante, Facelets proporciona un framework de plantillas para JSF. Con Facelets, puede utilizar un modelo de inyección de dependencias para ensamblar páginas en lugar de incluir manualmente el encabezado de página, pie de página, y los componentes de la barra lateral en cada página.

Seam UI Tags

Las etiquetas Seam dan acceso a los componentes JSF a la información manejada por Seam, en tiempo de ejecución. Ayudan a integrar los componentes de datos y negocio con más fuerza que con los componentes Web. Las etiquetas se dividen en las siguientes categorías:

  • Validación. Las etiquetas de validación Seam permiten hacer uso de las anotaciones de Hibernate validator sobre beans de entidad para validar campos de entrada de JSF. También permiten un campo si una validación falla
  • Manejo de la conversación. Un concepto clave en Seam es la arbitrariedad de la longitud de la conversación web. Normalmente, las páginas web de las conversaciones están conectadas mediante campos ocultos en las operaciones HTTP POST. Pero ¿Qué pasa si se quiere hacer click sobre un hipervínculo regular y mantenerse en la misma conversación? Seam provee de las etiquetas que pueden realizarlo.
  • Manejo de los procesos de negocio. Seam proporciona etiquetas que pueden asociar el contenido de la página web con los procesos de negocio asociados.
  • Rendimiento. La etiqueta <s:cache> engloba al contenido de la página que debe ser cacheado en el servidor. Cuando la página se reproduce de nuevo, la región cacheada se carga desde la caché en lugar de ser reproducida dinámicamente.
  • Etiquetas para reemplazar a JSF. Algunas etiquetas están destinadas a reemplazar algunas deficiencias detectadas en JSF. Actualmente la única disponible es <s:convertDateTime>.

Mejoras introducidas por Seam en la persistencia de objetos

Con la llegada de EJB 3 y JPA nace la figura del EntityManager para simplificar la persistencia de objetos. Y gracias a las anotaciones, el EntityManager puede ser inyectado por el contenedor de EJBs. Vamos a ver diferentes formas de obtener un EntityManager en Seam a través de anotaciones.

  • El EntityManager es inyectado directamente por el EJB container, y estará disponible incluso después de que la transacción haya sido completada. Las entidades pueden seguir asociadas al contexto de persistencia durante varias interacciones.
@PersistenceContext(type=PersistenceContextType.EXTENDED)
EntityManager entityManager;
  • El EntityManager es inyectado por Seam y asociado al contexto de conversación, con las mismas características que un EntityManager de tipo extendido.
@In EntityManager entityManager;

Mejoras introducidas por Seam en el lenguaje de expresiones (EL)

En el estándar de JSF, la propiedad (value expression) y el método (method expression) del componente respaldado son lo mismo. Como resultado, el método de expresión no puede hacer ninguna llamada con argumentos. Por ejemplo, la propiedad "name" sobre el componente persona se expresa de la siguiente manera:

<h:inputText value="#{person.name}" size="15"/>

El manejador de eventos del método sayHello() esta escrito de la misma manera, y tampoco puede hacer llamadas con argumentos. Todos los objetos del método deben ser inyectados en el método previamente a que el método sea llamado, como por ejemplo:

<h:commandButton type="submit"
value="Say Hello"
action="#{manager.sayHello}"/>

Seam extiende el lenguaje EL, ahora puedes llamar a cualquier componente con el () para mejorar la lectura. Por lo tanto el método puede realizar llamadas con argumentos también. Así, ya no es necesario introducir inyección del componente "person" sobre el componente "manager". Esto reduce las necesidades para la inyección de dependencias y convierte lectura en la aplicación en un forma más sencilla:

<h:commandButton type="submit"
value="Say Hello"
action="#{manager.sayHello(person)}"/>

Así la nueva clase del ManagerAction quedaría con el nuevo método sayHello() de la siguiente manera:

@Stateless
@Name("manager")
public class ManagerAction implements Manager {
  private Person person;
  @Out
  private List <Person> fans;
  @PersistenceContext
  private EntityManager em;
  public void sayHello (Person p) {
  em.persist (p);
  fans = em.createQuery("select p from Person p").getResultList();
 }
}

La mejora en el uso del EL permite realizar llamadas con argumentos separado por comas. Si el argumento a pasar es una cadena de texto literal, se puede pasar directamente en el EL como el ejemplo siguiente:

... action="#{component.method('literal string')}"/>

Seam no solo hace expansión del lenguaje EL, también permite que el lenguaje EL esté disponible más allá de las paginas web. En una aplicación Seam, puedes usar expresiones JSF para substituir código estático en ficheros de configuración, tests, mensajes JSF, etc. El uso expandido del lenguaje EL de JSF simplifica el desarrollo.

Filtro Seam

Seam proporciona un filtro para el servlet muy potente. El filtro realiza un procesamiento adicional antes de que la petición se procese por JSF y después de que se genere la respuesta de la web. Es una mejora en la integración de de los componentes Seam y JSF

  • El filtro preserva el contexto JSF de la conversación durante el redireccionamiento de URL. Eso permite que el ámbito de la conversación por defecto de Seam abarque desde la página de solicitud a la página de respuesta redirigida.
  • Captura cualquier error en tiempo de ejecución no detectado y redirige a páginas de error personalizadas o la página de Seam para la depuración, si es necesario
  • Proporciona apoyo para la carga de archivos de componentes JSF en los componentes Seam.
  • Permite a cualquier servlet no JSF o una página JSP para acceder a los componentes Seam a través de la clase Seam Component class.

Ejemplos

  • El recurso dispone de ejemplo sobre las diversas características funcionales.