etiquetas - jsf ejemplo
Localización en JSF, cómo recordar la configuración regional seleccionada por sesión en lugar de por solicitud/vista (5)
faces-config.xml
:
<application>
<locale-config>
<default-locale>ru</default-locale>
<supported-locale>ua</supported-locale>
</locale-config>
</application>
En un método de acción de frijol, estoy cambiando la configuración regional en la vista actual de la siguiente manera:
FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua"));
El problema es que ua
Locale se aplica, pero solo por solicitud / vista y no por sesión. Otra solicitud / vista dentro de la misma sesión restablece la configuración regional de nuevo al valor ru
predeterminado.
¿Cómo puedo aplicar la configuración regional para la sesión?
Este componente f: ver no está ahí, su página JSF no funcionará y mostrará solo el idioma inglés predeterminado. Proporcione el valor local para este componente f: view, entonces funcionará bien. Enfrenté el mismo problema ahora está funcionando bien.
Necesita almacenar la configuración regional seleccionada en el ámbito de la sesión y establecerla en la raíz de visualización en dos lugares: una vez por UIViewRoot#setLocale()
inmediatamente después de cambiar la configuración regional (que cambia la configuración regional de viewroot actual y así se refleja en la devolución; esta parte no es necesaria cuando realiza una redirección después) y una vez en el atributo de locale
de <f:view>
(que establece / conserva la configuración regional en las siguientes solicitudes / vistas).
Aquí hay un ejemplo de cómo debería ser un LocaleBean
:
package com.example.faces;
import java.util.Locale;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
@ManagedBean
@SessionScoped
public class LocaleBean {
private Locale locale;
@PostConstruct
public void init() {
locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}
public Locale getLocale() {
return locale;
}
public String getLanguage() {
return locale.getLanguage();
}
public void setLanguage(String language) {
locale = new Locale(language);
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
}
}
Y aquí hay un ejemplo de la vista que debería verse así:
<!DOCTYPE html>
<html lang="#{localeBean.language}"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:view locale="#{localeBean.locale}">
<h:head>
<title>JSF/Facelets i18n example</title>
</h:head>
<h:body>
<h:form>
<h:selectOneMenu value="#{localeBean.language}" onchange="submit()">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="nl" itemLabel="Nederlands" />
<f:selectItem itemValue="es" itemLabel="Español" />
</h:selectOneMenu>
</h:form>
<p><h:outputText value="#{text[''some.text'']}" /></p>
</h:body>
</f:view>
</html>
Tenga en cuenta que <html lang>
no es necesario para el funcionamiento de JSF, pero es obligatorio cómo los bots de búsqueda interpretan su página. De lo contrario, posiblemente se marcará como contenido duplicado, lo que es malo para SEO.
Relacionado:
Si puede usar CDI y deltaspike ( módulo JSF ) en su entorno, puede agregar lo siguiente a su LocaleBean
para restablecer automáticamente la configuración regional en la vista actual:
@javax.enterprise.context.SessionScoped
public class LocaleBean implements Serializable {
...
public void resetLocale(@Observes @BeforePhase(JsfPhaseId.RENDER_RESPONSE) PhaseEvent event) {
event.getFacesContext().getViewRoot().setLocale(this.locale);
}
}
Un pequeño comentario a @BalusC gran solución. Si tenemos <f:viewAction>
que ejecuta algún método en backing bean. La FacesContext.getCurrentInstance().getViewRoot().getLocale()
regional disponible de call a FacesContext.getCurrentInstance().getViewRoot().getLocale()
dentro de ese método sería la configuración regional configurada por el navegador del usuario o la configuración regional de la aplicación predeterminada, no la configuración regional configurada en bean de sesión por selección del usuario (por supuesto pueden coincidir si la configuración regional del navegador es igual a la configuración regional que el usuario seleccionó).
Puedo quedar corregido, porque quizás hice algo mal al implementar la solución provista por @BalusC.
EDITAR. Después de jugar con el ciclo de vida JSF , este comportamiento con la configuración regional no está relacionado con <f:viewAction>
, porque también existe un comportamiento similar con @PostContruct
. <f:view locale="#{localeBean.locale}">
in request (después de la configuración regional seleccionada por el usuario) se ejecuta en la fase de respuesta de renderizado. @PostContruct
métodos <f:viewAction>
y @PostContruct
se ejecutan en la fase de solicitud de invocación. Es por eso que la lógica que se ejecuta en este método no tiene acceso a la configuración regional seleccionada por el usuario.
La solución que usamos cuando necesitamos una configuración regional correcta es inyectar (CDI) localeBean
en otro bean de respaldo que contenga los métodos <f:viewAction>
y @PostContruct
, y luego establecer la configuración regional con UIViewRoot#setLocale()
de localeBean
en el inicio de estos métodos.
Veo que el problema también está con el nombre del archivo .properties. Java Locale us codes (minúsculas) como: en_gb Pero la configuración regional creada automáticamente (por Netbeans) es lowercase_uppercase, es decir: messages_en_GB.properties Cambia el nombre a: messages_en_gb.properties y debería funcionar, si lo intentaste todo