sábado, 22 de agosto de 2009

Spring MVC Implementando Internacionalización

La internacionalización de tu aplicación consiste en hacerla accesible no solo para las personas localizadas en un país(con un determinado lenguaje, como el español para nosotros), sino tambien para aquellas personas en otros países(como Inglaterra, Francia ó Italia, que leen inglés, francés, italiano) La internacionalización consiste básicamente en que el texto que muestra tu aplicación en un determinado lenguaje pueda ser visto en otro lenguaje si cambiar nada de código, es decir si desde Italia accedo a tu aplicación entonces todo el texto tiene que estar en italiano, si desde Inglaterra accedo a tu aplicación entonces todo el texto tiene que estar en inglés. Pero, ¿como implementamos esto? ¿cuál es la mejor manera?. A veces cuando no se tiene un conocimiento profundo de la tecnología realizamos la aplicación sin tener en cuenta este punto osea implementamos todas los texto solo en nuestro lenguaje, para muestra un ejemplo:

- Si tenemos un pedaz de código en una página jsp como el siguiente:
Usuario: <input type="text" name="usuario"/>
Clave: <input type="text" name="clave"/>

-Entonces el texto(ó etiquetas) Usuario y Clave siempre van a aparecer en español para cualquier tipo de usuario(sea inglés, italiano, alemán...)

La solución está en asociar claves a las etiquetas y centralizar esta asociación en un archivo de propiedades, teniendo un archivo por cada lenguaje que desee soportar nuestra aplicación. El código jsp anterior se puede cambiar por lo siguiente:

<spring:message code="etiq.usuario"/><input type="text" name="usuario"/>
<spring:message code="etiq.clave"/><input type="text" name="clave"/>

Y el archivo de propiedades para tres idiomas sería:
1. Para soporte español(por defecto cuando el sufijo no es especificado)
mensajes.properties
etiq.titulo = Spring Framework
etiq.usuario = Usuario
etiq.clave = Clave

2. Para soporte inglés
mensajes_EN.properties
etiq.titulo = Spring Framework
etiq.usuario = User
etiq.clave = Password

3. Para soporte italiano
mensajes_IT.properties
etiq.titulo = Spring Framework
etiq.usuario = Utente
etiq.clave = Chiave

Cuando la aplicación sea invocada esta va a detectar el lenguaje del navegador y va a utilizar el archivo de propiedades apropiado.

Bueno, ahora veamos como Spring soporta todo este contexto de internacionalización. A diferencia de los post anteriores ahora vamos a agregar a la aplicación un contenedor de beans(un ApplicationContext.xml) adicionando al descriptor de despliegue lo siguiente:

<!--
Una variable de contexto que tendrá como valor el archivo de configuración del contenedor de beans.
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<!--
Un listener de contexto que usará el archivo anterior para instanciar todos los beans que contiene
-->
<listener><listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class></listener>

Una vez declarado la ruta del contenedor de beans ahora lo definimos:
ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!--
Declaración del bean que obtendrá el archivo y que a su vez lo hará disponible al resto de la aplicación(ya no tenemos que colocar los mensajes en duro) ahora podemos centralizar estos mensajes en un archivo mensajes.properties, este archivo debe de estar en la raiz de tu classpath, osea /WEB-INF/classes
-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename"><value>mensajes</value></property>
</bean>
</beans>

Los archivos de propiedades con los textos en cada idioma debemos de colocarlos en la raiz del classpath, es decir en /WEB-INF/classes . Esta carpeta quedaría como:

/WEB-INF/classes/mensajes.properties
/WEB-INF/classes/mensajes_EN.properties
/WEB-INF/classes/mensajes_IT.properties

Una vez configurada la aplicación procedemos a probarla con un archivo jsp:
index.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><spring:message code="etiq.titulo"/></title>
</head>
<body>
<form action="/usuario/procesar.do" method="POST">
<spring:message code="etiq.usuario"/><input name="usuario" type="text"/>
<spring:message code="etiq.clave"/><input name="clave" type="text"/>
</form>
</body>
</html>

Para finalizar, este tipo de diseño simplifica el desarrollo y mantenimiento de tu aplicación, ya no tienes que estar buscando en las miles de líneas de código en tu aplicación, todos los mensajes y textos los centralizas en un archivo de mensajes y si quieres cambiar algo, pues solo lo haces allí.


4 comentarios:

  1. Muy bueno hermano.

    Saludos.

    ResponderBorrar
  2. ¿Y cómo le indicas el idioma que quieres?

    ResponderBorrar
  3. Buenas!!! se que la entrada es de hace tiempo pero tengo algo muy "raro". He montado un spring MVC 4.0 con spring Security y le meti multidioma, el caso es que para el Login el spring:message funciona perfectamente pero en el resto del proyecto no me funciona.... Porque podria ser???

    ResponderBorrar

Es bueno comunicarnos, comenta!!.