Selección manual de idioma en la interfaz de usuario con JSF2.

2
8964

Selección manual de idioma en la interfaz de usuario con JSF2.

0. Índice de contenidos.


1. Introducción

JSF, como framework que proporciona soporte para la generación de interfaces visuales basadas en componentes y una capa de control que gestiona los eventos que se producen en el cliente, permite de una manera muy sencilla configurar la internacionalización de literales en la vista.

El patrón que se sigue para asignar al contexto de JSF el idioma seleccionado es obtenerlo de la petición, en función del idioma que tenga asignado el cliente a nivel de navegador.

En este tutorial vamos a exponer como permitir la selección manual del idioma, por ejemplo, en una primera página de login, de modo que, en vez de asignarse el idioma a nivel de navegador, prime el idioma seleccionado por el usuario en un combo de selección.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2.4 GHz Intel Core i7, 8GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Lion 10.7.4
  • JSF 2.1.12


3. Implementación.

Primero vamos a mostrar el código necesario en esa página inicial, la de login, para pintar un combo de selección de idiomas:

	<div id="localeSwitcher">
		<h:form>
			<h:selectOneMenu value="#{localeSwitcher.locale}"
				valueChangeListener="#{localeSwitcher.localeChangeListener}" converter="selectItemsConverter" > 
				 <f:selectItems value="#{localeSwitcher.supportedLocales}" var="locale" 
				 	itemLabel="#{locale.displayLanguage}" itemValue="#{locale}" />
				 <f:ajax render="@all"/>
			</h:selectOneMenu>
		</h:form>
	</div>

Hacemos uso de un conversor para SelectItems que nos facilita la asignación directa de un objeto de tipo Locale y,
con ello, el soporte del lado de la capa de control para mostrar los idiomas disponibles, recoger el seleccionado y almacenar la selección en la sesión, lo proporciona el siguiente ManagedBean

package com.autentia.training.web.view;

import java.io.Serializable;
import java.util.List;
import java.util.Locale;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;

import org.apache.commons.collections.IteratorUtils;

@ManagedBean
@SessionScoped
public class LocaleSwitcher implements Serializable {

	private static final long serialVersionUID = 84157941310458440L;

    private Locale locale;

    private List<Locale> supportedLocales;
    
    @PostConstruct
    protected void init(){
    	locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    	this.supportedLocales = IteratorUtils.toList(FacesContext.getCurrentInstance().getApplication().getSupportedLocales());
    }
    
    public Locale getLocale() {
        return locale;
    }
    
    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    public void localeChangeListener(ValueChangeEvent changeEvent) {
        locale = ((Locale) changeEvent.getNewValue());
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

	public List<Locale> getSupportedLocales() {
		return supportedLocales;
	}

}

Como siempre, un ManagedBean debe ser un POJO de modo que los métodos setters y getters no deben tener lógica de control. Siguiendo esta premisa, en un método de inicialización anotado con @PostContruct recuperamos tanto el locale asignado inicialmente como el listado de idiomas soportados en la configuración de nuestro faces-config.xml.

Por último, para que las interfaces de usuario tomen el idioma seleccionado en la página inicial y asignado a la sesión, debemos incluir un elemento f:view con un atributo que apunte al método del controlador de sesión que guarda la referencia del idioma seleccionado:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
	 
<f:view locale="#{localeSwitcher.locale}">
<h:head>
...

El componente f:view, hasta la llegada de facelets al mundo de JSF era obligatorio incluirlo como nodo raíz de nuestros árboles de componentes; ahora ya no, pero si queremos asignar el locale manualmente al árbol de componentes debemos incluirlo.

Si estamos trabajando con un sistema de plantillas, solo tendremos que incluirlo en la plantilla que contiene el layout de nuestra interfaz.

Si además incluimos el elemento f:view en la página de login, podremos comprobar el switch direntamente en la página de autenticación. Así, un ejemplo de la página en español:

y en inglés:



4. Conclusiones.

Simple, pero efectivo 😉

Un saludo.

Jose

jmsanchez@autentia.com

2 COMENTARIOS

  1. Estoy entrando en el mundo de JSF y al intentar lo que explica el articulo, me queda la duda de como se hace en si el cambio de idioma? se tiene que crear un nuevo archivo bundle por cada idioma y después se hace el cambio con el BEAN… agradeceria su apoyo

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad