sábado, 1 de abril de 2017

En el tutorial Spring i18N vimos como este framework nos facilita el soporte para varios idiomas, aplicaremos la teórica aprendida en aquel tutorial y crearemos una aplicación web con Spring MVC que soporte varios idiomas, en este ejemplo, español e inglés, aunque con los conceptos aprendidos te será fácil añadir mas idiomas.

Utilizaremos el proyecto Spring MVC Formularios Thymeleaf como base para este ejemplo, el proyecto se mantendrá igual solo agregaremos el soporte para varios idiomas.

@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"carmelo.spring.controller"})
public class WebAppConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        this.applicationContext = ac;
    }

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        return messageSource;
    }

    @Bean
    public LocaleResolver localeResolver() {
        return new SessionLocaleResolver();
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(this.applicationContext);
        templateResolver.setPrefix("/WEB-INF/templates/");
        templateResolver.setSuffix(".html");
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.setEnableSpringELCompiler(true);
        return templateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        return viewResolver;
    }
}

La mayoría de los bean definidos en esta clase los vimos en el tutorial anterior, para soportar i18n requerimos estos tres:

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;
}

@Bean
public LocaleResolver localeResolver() {
    return new SessionLocaleResolver();
}

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName("lang");
    return localeChangeInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
}

El primero nos sirve para definir los archivo donde se guardaran las distintas traducciones de los textos, estos archivos tendrá en nombre base messages, para agregar la traducción al inglés deberemos agregar el archivo messages_en.properties, para español messages_es.properties, podemos seguir agregando los idiomas que deseemos.

El bean LocaleResolver establece el lugar en donde se almacenará la información del idioma que utiliza el usuario, SessionLocaleResolver guarda esta información en la sesión, existen más implementaciones por ejemplo CookieLocaleResolver que guarda la información en una cookie.

Por último tenemos el bean LocaleChangeInterceptor este intercepta la petición HTTP y cambia el idioma actual si la URL contiene el parámetro lang=idioma donde idioma es el código del lenguaje deseado: en, es, fr, uk, etc., el nombre del parámetro lo establecemos con el método setParamName("..."), en nuestro ejemplo lo llamaremos lang.

  • Para cambiar a español: www.tutoriales.com/spring?lang=es
  • Para cambiar a inglés: www.tutoriales.com/spring?lang=en

Sobre-escribimos el método addInterceptors(InterceptorRegistry registry) para registrar el interceptor, este método es heredado de la clase WebMvcConfigurerAdapter.

Los mensajes traducidos a diferentes idiomas los almacenamos en los siguientes archivos:

spring mvc i18n

Si utilizas el IDE Netbeans 8.x puedes hacer clic derecho sobre alguno de estos archivos y presionar la opción Open, se abrirá la siguiente ventana.

netbean i18n

Aquí podrás añadir las traducciones de una manera mas sencilla, aunque también puedes abrir el archivo el el editor de texto y agregar las traducciones.

src/main/resources/messages_en.properties

form.user.nombre=User name
form.user.apellido=Last name
form.user.correo=Email
form.user.edad=User age
form.user.sexo=Gender
form.user.pass=Password
form.user.boton=Send...

src/main/resources/messages_es.properties

form.user.nombre=Nombre del usuario
form.user.apellido=Apellido materno y paterno
form.user.correo=Correo electronico
form.user.edad=Edad del usuario
form.user.sexo=Eres hombre
form.user.pass=Tu contraseña
form.user.boton=Enviar...

Este nos es tutorial de ingles, así que, disculpen la traducción.

Para finalizar lo mas normal es que en nuestra vista tengamos la opción de cambiar de idioma, hacerlo es muy simple, solo añadiremos dos enlaces, cada uno inserta el parámetro lang correspondiente al idioma,al hacer clic sobre el inmediatamente veremos los textos traducidos.

<div style="padding: 10px; border: 1px solid gray;">
    <a href="?lang=es">Spanish</a>
    <a href="?lang=en">English</a>
</div>

La aplicación en español:

image

La aplicación en ingles:

image

Recordemos que en una vista Thymeleaf obtenemos el correspondiente mensaje utilizando el siguiente atributo: th:text="#{form.user.nombre}" donde dentro de #{...} va la clave de la propiedad que deseamos mostrar en la vista.

Si utilizas una vista JSP deberás incluir el correspondiente taglib para poder acceder a los mensajes del archivo de propiedades.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
...
<span><spring:message code="form.user.nombre" /></span>

La etiqueta <spring:message code="..." /> nos permite obtener el respectivo mensaje.

Los mensajes de error producidos por Hibernate Validator están internacionalizados, sin embargo, si definimos nuestros propios mensajes debemos recordar definir también la correspondiente traducción. 

0 comentarios :

Publicar un comentario