Traducir una página JSF con Java

TraducirCon la penetración que está teniendo el Internet en todo el mundo, cada vez es más importante traducir nuestras páginas web, debido a que los visitantes ya pueden venir de cualquier parte del mundo, es por eso que los sitios más importantes o que buscan captar visitantes de otras regiones, permitan a sus usuarios cambiar de idioma.

Pueda que de entrada parezca algo muy complicado o laborioso de hacer, sin embargo, es mucho más simple de lo que te puedas imaginar.

 

Para explicar cómo funciona la Internacionalización (I18N), lo explicaremos mediante un ejemplo simple pero eficaz, implementaremos una página de Login, la cual se verá de la siguiente manera:

 

Traducir

El código completo lo puedes descargar de GitHub (https://github.com/oscarjb1/Blog-TranslateApp.git).

 

Básicamente, esta página nos permitirá cambiar entre inglés y español, seleccionando el idioma deseado en la parte superior derecha de la pantalla. Tras seleccionar el nuevo idioma, la página de recargara con el nuevo idioma.

 

Veamos cómo es que esto es posible. Primero que nada, será necesario crear un archivo properties por cada idioma que soportará nuestra aplicación. Para nuestro ejemplo, solo requerimos de dos archivos como se ven a continuación:

 

messages.properties:

Contiene las traducciones por default, en este caso Ingles.

 

 

message_es_ES.properties:

Contiene las traducciones en español. Prestemos atención en el nombre, pues es sumamente importante, la primera parte message  podría tener cualquier valor, pero todos los idiomas soportados deberán iniciar con el mismo nombre., sin embargo, lo que viene a continuación es sumamente importante para identificar el idioma, la segunda sección es  indica el idioma (español) y la tercera parte ES  el país (España).

 

Podemos observar que las traducciones en inglés, no requieren país ni idioma, pues los hemos configurado como el idioma default, esto quiere decir que este idioma se utilizara en caso de no tener una coincidencia para el idioma del usuario.

 

Para configurar el idioma default, es necesario definirlo en el archivo faces-config.xml y deberá quedar de la siguiente manera:

 

 

Básicamente definiremos el idioma default ( <default-locale> ) y los idiomas soportados ( <supported-locale>). La sección <base-name> debe de coincidir con el paquete en el que están los archivos de traducción, junto con la primera sección del nombre (messages). De esta forma JSF sabe, basado en este path + el idioma y el país, es posible determinar el archivo exacto a utilizar.  Finalmente, le indicamos que las traducciones las pase a una variable ( <var> ) llamada msg.

 

Por otra parte, tenemos el archivo JSF donde creamos la presentación:

 

Observemos que todos los valores traducibles están con la sintaxis #{msg[property]} , donde property es el nombre de la propiedad a traducir de los archivos de traducción.

La traducción se dispara cuando cambiamos el idioma en el componte, selectOneMenu el cual dispara un evento que es escuchado por el Bean LoginBean , el cual vemos a continuación:

 

 

Cuando un nuevo idioma es seleccionado el método changeLang es ejecutado y el nuevo idioma es establecido mediante la línea:

viewRoot.setLocale(new Locale(newValue.toString()));

Después de esto, la pantalla es recargada con el nuevo idioma. Es tan simple como eso.

 

NOTA: Los estilos para que la página se vea tal cuan aparece en la imagen, los puedes descargar del repositorio de GitHub que menciona anteriormente.

Artículos relacionados

Java – Como eliminar rápidamente elementos r... Hace tiempo un amigo me preguntaba  como podía eliminar los elementos repetidos de una colección sin hacer mucho esfuerzo. Bien la solución que consid...
toString elegantes con ReflectionToStringBuilder En esta ocasión les quiero platicar de una fantástica clase de utilidad que yo he utilizado con frecuencia en el desarrollo de software, Esta clase ...
Java – Weakreference Este tema hasta para los expertos en java les puede resultar desconocido y es que siempre creemos que un objeto que no esta referenciado por ninguna v...

Oscar Blancarte

Ideológico, Innovador y emprendedor, Padre, Tecnólogo y Autor, amante de la ciencia y la tecnología en todos sus colores y sabores. Arquitecto de software & Full Stack Developer con experiencia en la industria del desarrollo de software y la consultoría. Amante de la programación y el Ajedrez.

2 comentarios en “Traducir una página JSF con Java

  1. Oscar buen día. Soy Luis Carlos, escribo desde Colombia. Hace un par de años escribí sobre adf java jsf weblogic, en ese entonces estaba incursionando con esas herramientas. Hoy en día estoy en un proyecto de esos, aprendiendo cosas.

    Quería hacerle una consulta, imagino que aún está activo ayudando en su blog, así que quisiera molestarlo con una nueva consulta, asi que lo contextualizo al respecto para que por favor me dé su recomendación como siempre.

    Tengo una jsf nueva llamada asignacionCarga que es una réplica de otra jsf llamada estadosFormulario, prácticamente lo que hice fue copiar y pegar la consulta original de estadosFormulario en mi jsf asignacionCarga, solo hice pequeños ajustes porque es una consulta que ya está funcionando bien en otro módulo y me funciona correctamente en mi nueva jsf. El inconveniente inició porque al hacer la copia de toda esa funcionalidad en mi jsf el IDE jdeveloper me mostró, dentro de mi jsf, las referencias hacia el Bean como si fueran errores, es decir, referencias como:
    value=”#{backingBeanScope.backing_pageCritico_estadosFormulario.listaAnios}”
    las tuve que cambiar a:
    value=”#{backing_pageCritico_estadosFormulario.listaAnios}”

    , …es decir tuve que quitarle el scope del Bean “backingBeanScope” y también tuve que cambiar el alcance del Bean en adf-config.xml, es decir, de :
    backingBean
    lo tuve que cambiar a:
    session
    De esta forma el IDE quitó los supuestos errores de las referencias.

    La base del inconveniente es que al salir de esa jsf asignacionCarga ir a otra jsf directamente a través del menú de la aplicación y regresar a la jsf asignacionCarga, todos los componentes como Select one choice y Table siguen cargados con las mismas selecciones, datos y valores que se utilizaron previamente en la jsf asignacionCarga, es decir al regresar a esa jsf no se blanquean los componentes ni campos de captura ni nada, todo sigue cargado como quedaron cuando se cargó la jsf por ultima vez. Dado que para levantar los supuestos errores del IDE (con las referencias hacia el Bean) tuve que dejar el alcance como “sesión” que mantiene todos los valores de las variables y demás mientras dure la sesión, pues menos se me van a blanquearan los valores cuando salga y vuelva a la misma jsf. Así las cosas probé cambiar nuevamente el alcance del Bean, y lo dejé como:
    view
    Con este alcance “view” me blanquea los componentes de la jsf cada vez que regreso a esa jsf, pero el tema es que el IDE volvió a mostrar las referencias como errores, aunque desplegó bien, y corrió bien la aplicación, y se comportó bien.

    La idea hubiera sido seguir usando el alcance: backingBean usado en la jsf estadosFormulario y sin necesidad de cambiar las referencias ni el alcance en mi jsf asignarCarga. Mi pregunta es si ese alcance “backingBean“ debo registrarlo o definirlo en algún otro lado del proyecto para que el IDE no me muestre como error todas esas referencias. Es decir si cambio backingBean y utilico otro alcance para el Bean, el IDE me pone como errores todas las referencias dentro de mi jsf.

    Cualquier recomendación agradezco,
    Saludos desde Colombia.

    1. Ups… tu pregunta es demasiada especifica como para darte una respuesta acertada, mi consejo es que cuides bien los Scope de los Beans, en ningún caso te recomiendo usar un Scope de Sesión para guardar los datos de un formulario, pues se mantendrá los valores durante toda la sesión, creo que la mejor opción es que utilices un View Scope o si es posible Request Scope.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *