Envío de correo electrónico con el soporte de Jboss Seam.

Envío de correo electrónico con el soporte de Jboss Seam.


0. Índice de contenidos.


1. Introducción.

Jboss Seam nos da soporte para el envío de correo electrónico, con una característica bastante interesante que radica en el hecho de que las plantillas de correo pueden generarse con facelets.

Ya hemos visto en otros tutoriales cómo enviar emails haciendo uso de las facilidades del framework de desarrollo con el que estemos trabajando, en el caso de Spring tenemos este tutorial y otros mas avanzados. Ahora es el turno de Jboss Seam y vamos a hacer uso de este tutorial para comentar otras características colaterales al propio servicio de envío de correo electrónico, que salen a la luz por la necesidad de configurar el buzón de correo en función del entorno, así veremos la posibilidad de cargar los valores de un fichero de propiedades en el entorno del fichero de configuración de Seam (components.xml) y la posibilidad de declarar un componente de Seam a través de la configuración de dicho xml inyectando ciertos valores de configuración.

El objetivo es el de disponer de un servicio propio, un componente de Seam, configurado para el envío de correo electrónico y que pueda ser inyectado en cualquier componente que requiera su uso. Mostraremos cómo crear una plantilla base para el envío de correo con el soporte de facelets de modo que establezca la estructura básica de la misma.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 17′ (2.93 GHz Intel Core 2 Duo, 4GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.1
  • Jboss Seam 2.2.0.GA
  • Maven 2.2.1.
  • Eclipse 3.5: Galileo, con IAM (plugin para Maven).
  • GlassFish v.2.1 con la jdk 1.6.

3. Configuración.

El soporte para el envío de email es un módulo de Seam que no se distribuye con las librerías del core, con lo que lo primero que debemos hacer es incluir la dependencia en el módulo que lo necesite:

En nuestro caso ${seam.version} es una propiedad que tenemos definida a nivel de pom.xml para su reutilización, su valor es 2.2.0.GA.

Para habilitar el soporte de email debemos incluir lo siguiente en el fichero de configuración de Seam (components.xml):

También se puede configurar, vía jndi, contra una sesión de mail configurada a nivel de servidor de aplicaciones, nosotros optamos por la vía de una configuración a nivel de aplicación puesto que el acceso a través de jndi ya nos dio problemas a la hora de configurar el servicio de autorización y autenticación (JAAS) contra GlassFish.

En los valores de los atributos de la configuración del correo lo que hacemos es introducir una serie de claves, comprendidas entre arrobas, que hacen referencia a entradas en un fichero de propiedades que Jboss Seam nos permite externalizar de modo que basta con incluirlo en el classpath del servidor (en el caso de GlassFish dentro de /glassfish/domains/domain1/lib/classes) con el nombre components.properties. Conforme a lo configurado, dicho fichero de propiedades, debería tener un contenido similar al siguiente:

La primera y las dos últimas entradas del fichero las usaremos en el siguiente punto.


4. Servicio de envío de email.

Antes de mostrar la clase que implementará el servicio, vamos a apoyarnos en una clase que encapsulará las características típicas de emisor y receptor del correo electrónico. Con ello en la plantilla mostraremos la posibilidad de acceder a objetos complejos.

Ahora sí, el contenido de la clase de implementación del servicio podría tener un contenido como el que sigue:

Tiene las siguientes características:

  • tres propiedades que nos van a permitir asignar:
    • si el servicio está activo o no, ideal para marcarlo como inactivo en el entorno de tests,
    • el nombre y el correo electrónico del remitente, que serán comunes para todos los emails enviados a través de este servicio. En este punto, aún teniendo inicializado el objeto from de tipo MailUser, vía inyección de dependencias no podemos inyectar valores en atributos compuestos como con Spring, de ahí la necesidad de los métodos setFromEmail y setFromName.
  • dos métodos para realizar el envío del correo electrónico (uno con parámetros y otro no) que reciben el nombre de la plantilla que deben cargar para componer el cuerpo y las características del mensaje y el destinatario del correo encapsulado en un objeto de tipo MailUser.
  • la asignación de las propiedades del correo se realiza a través de la inserción de las mismas en el contexto de sesión y el envío se realiza mediante un renderizador. Esto último es lo más interesante puesto que la plantilla es facelets y lo que se ejecuta es la última fase del ciclo de vida de JSF, la de renderización, para el árbol de componentes que contiene la plantilla. Dentro de la plantilla se podrán tener referencias a las propiedades asignadas a través del contexto o incluso a aquellos componentes de Seam con un ámbito de sesión.
  • la plantilla de facelets, el render la obtiene del classpath con un prefijo y sufijo predeterminados.

La clase no está anotada para que se incluya de forma automática como un componente de Seam porque requiere de ciertas propiedades que obtenemos del fichero de configuración de entorno (components.xml) antes expuesto y, para ello, tenemos que obtenerlas mediante las claves indicadas en el punto anterior.

Para publicar el servicio debemos incluir lo siguiente en el fichero de configuración de Seam (components.xml):

Con ello, todas las propiedades relativas a la configuración del servicio de correo quedan externalizadas en el fichero de propiedades (components.properties) y, de este modo, en el entorno de tests podemos hacer uso de otro fichero de propiedades que deshabilite el servicio de correo para evitar el envío innecesario de emails en la ejecución de las pruebas.


5. Ejemplo de uso del servicio.

A continuación vamos a mostrar un ejemplo de uso del servicio, en el que un usuario puede solicitar el refresco de su contraseña tras haberla olvidado.

A destacar lo siguiente:

  • 19: la inyección del servicio de envío de email,
  • 21: la inyección del contexto de mensajes de notificación al usuario en la respuesta,
  • 33: la clase de utilidades de Seam RandomStringUtils que nos permite generar una cadena con caracteres aleatorios en función de una longitud dada,
  • 35: la invocación al servicio de envío pasándole el nombre de la plantilla y la información del usuario conectado a la aplicación.
  • 37: el hecho de añadir un mensaje al contexto para informar del envío correcto del email.

A continuación vemos el contenido de la plantilla de email relacionada con el olvido de la contraseña en la que nos limitamos a definir el contenido de subject y del cuerpo del mensaje, basándonos en el soporte a la internacionalización de JSF y en la referencia a las propiedades asignadas por el servicio e incluso en propiedades del controlador que realiza el envío (como la nueva contraseña generada).

Lo más interesante es que la plantilla, a su vez, hace uso de una plantilla de facelets (template=”/WEB-INF/facelets/template/email.jspx”), cuyo contenido veremos después.

El texto internacionalizado reside en ficheros de propiedades que hacen referencia al locale en su nombre y que deberían tener un contenido similar al siguiente:

Por último, el contenido de la plantilla maestra para todas las plantillas de email debería tener un contenido como el que sique:

Son componentes propios del módulo de envío de email que hacen referencia a las propiedades asignadas a nivel de contexto para el envío, y realizan la inserción del valor de variables declaradas en la plantilla que hace uso de la misma (el subject y el cuerpo del mensaje).


6. Asignación de la url del contexto de la aplicación como parámetro a la plantilla.

Para quienes trabajamos con JSF y facelets, el hecho de disponer de dicha tecnología a la hora de componer el contenido de un mensaje, nos podemos ver tentados a hacer uso de una expresión como la que sigue para obtener la url y el contexto de la aplicación:

Quizás lo necesitemos para inluir un link a la aplicación o una imagen.

Podría funcionar pero no, lo que imprime es siempre “project”, es un valor fijo. El contexto en el que se renderiza la plantilla de correo no es el de la petición del cliente con lo que no tenemos acceso a dicha información.

Podemos solventar el problema asignando una propiedad adicional al contexto de ejecución de la plantilla, como sique:

De este modo, desde la plantilla podemos hacer referencia al mismo, como lo hacemos con el resto de propiedades.


7. Referencias.


8. Conclusiones.

En este tutorial hemos analizado temas algo más avanzados de los que venimos tratando, relacionados con Jboss Seam.

Ya llevamos un tiempo trabajando con Seam, el suficiente para que ahora, con un cambio de versión, se vengan abajo los conocimientos consolidados… :-D, tenemos pendiente analizar la versión 3 (alpha aún) del framework que será, en su núcleo (WELD), la implementación de referencia del nuevo contenedor de inversión de control de JEE6.

Si estáis interesados en el contenido de nuestros tutoriales y tenéis una necesidad formativa al respecto no dudeis en poneros en contacto con nosotros. En Autentia nos dedicamos, además de a la consultoría, desarrollo y soporte a desarrollo, a impartir cursos de formación de las tecnologías con las que trabajamos.

Un saludo.

Jose

jmsanchez@autentia.com