Database MessageSource: obtener los literales de una base de datos

Database MessageSource: obtener los literales de una base de datos

0. Índice de contenidos.

1. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil Mac Book Pro 17″ (2,6 Ghz Intel Core i7, 8 GB DDR3)
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.4
  • Spring 3.1.0.RC1
  • Mybatis 3.0.4

2. Introducción

Lo más normal a la hora de internacionalizar aplicaciones es contar con ficheros de propiedades que almacenan los literales que se utilizan, los famosos ResourceBundle, que nos permite tener n ficheros cada uno del idioma que queramos visualizar. Este es el funcionamiento habitual a la hora de hacer i18n. En este tutorial vamos a ver como obtener estos literales almacenados en nuestra propia base de datos y seguir utilizando el estándar de Spring para no tener que cambiar el código de la aplicación, tanto para JSP’s cuando utilizamos la etiqueta <spring:message code=”code”/> o cuando utilizamos la interfaz MessageSource en nuestro código Java, así como la forma de parametrizar los mensajes.

3. Creación del proyecto de prueba

Como siempre vamos a demostrar lo que decimos y que mejor que crear un proyecto con Maven e importarlo a Eclipse. El proyecto va a utilizar Spring y Mybatis para el acceso a la base de datos, aquí tenéis un tutorial al respecto.

Definimos el pom.xml del proyecto de esta forma:

Ahora vamos a crear la tabla en la base de datos que va a almacenar los literales. Simplemente va a ser una tabla que va a tener 3 columnas:

  • codLiteral: almacena el código numérico del literal. INTEGER NOT NULL
  • literal: almacena el texto del literal. VARCHAR (400)
  • locale: almacena el idioma del literal. VARCHAR (10)

La clave primaria está compuesta por los campos codLiteral y locale, de forma que a través del mismo código vamos a poder recuperar el literal correspondiente al idioma deseado y no puede repetirse un mismo código para un mismo locale.

Cargamos una serie de datos de prueba.

Ya tenemos el entorno de desarrollo preparado.

4. Vamos al lío

Lo primero que tenemos que resolver es el acceso al literal dado un código y un locale. Para ello vamos a crear el siguiente test:

Para la implementación del acceso a la base de datos utilizamos Mybatis, para lo cual definimos la interfaz LiteralMapper de esta forma:

La implementación del método definido se hace a través de un mapper en el fichero LiteralMapper.xml de esta forma:

La definición del fichero application-context-text.xml define la configuración de MyBatis y la definición del datasource de prueba.

Ejecutando este test tenemos que ver que pasa perfectamente y que recupera el literal indicado. De tal forma que ya tenemos un problema resuelto.

Ahora a por el siguiente. Vamos a implementar la clase que se encargue de internacionalizar los literales a través de Spring. Esta clase tiene que extender de AbstractMessageSource e implementar el método resolveCode. Pero antes vamos al test:

Como veis este código no difiere de la forma habitual de internacionalización de Spring. Tenemos tres tests: el primero de ellos nos devuelve el texto en castellano, el segundo el mismo texto en inglés y el tercero nos devuelve un texto parametrizado.

Ahora creamos la clase DatabaseMessageSource que como ya hemos dicho tiene que extender de AbstractMessageSource e implementar el método resolveCode, para nuestro caso el código quedaría de la siguiente forma:

Simplemente accede a la base de datos con el código y el locale proporcionado para devolver el texto en un objeto MessageFormat gestionado por Spring. Ahora para que el test funcione tenemos que definir el bean “messageSource” indicando que va a ser implementado por la clase DatabaseMessageSource dentro del fichero application-context-test.xml.

Ahora ejecutamos el test y tenemos que ver que pasa perfectamente. Dejo como deberes ver como funciona también en aplicaciones web utilizando la etiqueta <spring:message code=”code”/>

5. Conclusiones

Como veis prácticamente todo ya está resuelto con Spring. Nuestro primer impulso podría ser crear nuestra propia clase que gestionará estos mensajes, pero eso supondría trabajar de una forma no estándar y acoplarnos completamente a esa solución, perdiendo las ventajas de trabajar con Spring.

Cualquier duda o sugerencia en la zona de comentarios.

Saludos.