JSF本地化,如何记住每个会话选定的区域设置,而不是每个请求/视图

faces-config.xml

 <application> <locale-config> <default-locale>ru</default-locale> <supported-locale>ua</supported-locale> </locale-config> </application> 

在一个bean操作方法中,我正在改变当前视图中的语言环境,如下所示:

 FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua")); 

问题在于ua语言环境已经被应用,但是仅仅是每个请求/视图而不是会话。 同一会话中的另一个请求/视图会将区域设置重置为默认的ru值。

我如何应用会话的语言环境?

您需要将选定的语言环境存储在会话作用域中,并将其设置在两个位置的viewroot中:在更改语言环境后立即通过UIViewRoot#setLocale()更改当前viewroot的语言环境,从而反映在回发中;这部分是不必要的,当你执行一个redirect之后)和一次在<f:view>locale属性(它设置/保留在后续的请求/视图的区域设置)。

下面是一个这样的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); } } 

这里是一个视图的例子应该是这样的:

 <!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> 

请注意, <html lang>不是JSF运行所必需的,但search漫游器解释您的页面是必须的。 否则,可能会被标记为对SEO不利的重复内容。

有关:

  • 使用UTF-8编码的属性文件在JSF 2.0中进行国际化

我看到的问题是与.properties文件名。 Java语言环境我们代码(小写),如:en_gb但自动创build的区域设置(由Netbeans)是lowercase_uppercase即:messages_en_GB.properties更改名称:messages_en_gb.properties,它应该工作 – 如果你尝试了一切

这个组件f:视图不存在你的JSF页面,它不会工作,它将只显示默认的英语language.Provide这个f:view组件的localae值,那么它会正常工作。 我现在面临同样的问题,工作正常。

一个小小的评论,以@BalusC伟大的解决scheme。 如果我们有<f:viewAction>在后台bean中执行一些方法。 在调用FacesContext.getCurrentInstance().getViewRoot().getLocale()方法的时候,locale可以通过用户浏览器或者默认应用程序的locale来设置,而不是通过用户select在session bean上设置的locale如果浏览器区域设置等于用户select的区域设置,则它们可以匹配)。

我可以纠正错误,因为在实现@BalusC提供的解决scheme时,我可能做错了什么。

编辑。 在玩JSF生命周期之后 ,locale的行为与<f:viewAction>没有关系,因为在@PostContruct也有类似的行为。 在请求中(在用户select的语言环境之后),在呈现响应阶段执行<f:view locale="#{localeBean.locale}"> 在调用应用程序阶段执行<f:viewAction>@PostContruct方法。 这就是为什么在这个方法中执行的逻辑不能访问用户select的语言环境。

当我们需要正确的语言环境时,我们使用的解决scheme是在包含<f:viewAction>@PostContruct方法的其他支持bean中注入(CDI) localeBean ,然后在localeBean中使用UIViewRoot#setLocale()设置locale。

如果您可以在您的环境中使用CDI和deltaspike( JSF模块 ),则可以将以下内容添加到您的LocaleBean以自动重置当前视图上的区域设置:

 @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); } }