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
Locale,但仅适用于每个请求/视图而不适用于会话。同一会话中的另一个请求/视图将语言环境重置为默认值
ru
值。 如何应用会话的区域设置?     
已邀请:
您需要将所选语言环境存储在会话范围中,并在两个位置将其设置在视图中:在更改语言环境后立即将其设置为
UIViewRoot#setLocale()
(这会更改当前视图的语言环境,从而反映在回发中;此部分不是在之后执行重定向时必需的)和在
<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>
请注意,JSF的运行不需要
<html lang>
,但搜索机器人如何解释您的页面是强制性的。否则它可能被标记为重复内容,这对SEO是不利的。 有关: 使用UTF-8编码的属性文件在JSF 2.0中进行国际化     
我看到问题也是.properties文件名。 Java Locale us代码(小写),如:en_gb 但是自动创建的语言环境(由Netbeans提供)是lowercase_uppercase,即:messages_en_GB.properties 将名称更改为:messages_en_gb.properties 它应该工作 - 如果你尝试了一切     
这个组件f:view不存在你的JSF页面它将无法工作,它将只显示默认的英语语言。为这个f:view组件提供localae值然后它将正常工作。我现在遇到了同样的问题它的工作正常。     
@BalusC的一个小问题很棒的解决方案。如果我们有
<f:viewAction>
,它在后台bean中执行某些方法。通过该方法调用
FacesContext.getCurrentInstance().getViewRoot().getLocale()
可以获得的语言环境是由用户浏览器或默认应用程序语言环境设置的语言环境,而不是用户选择在会话bean上设置的语言环境(当然,如果浏览器语言环境等于用户选择的语言环境,它们可以匹配)。 我可以纠正,因为在实施@BalusC提供的解决方案时,我可能做错了。 编辑。在使用JSF生命周期后,这种使用语言环境的行为与
<f:viewAction>
无关,因为与
@PostContruct
也有类似的行为。请求中的
<f:view locale="#{localeBean.locale}">
(在用户选择的区域设置之后)在渲染响应阶段执行。
<f:viewAction>
@PostContruct
方法在调用应用阶段执行。这就是为什么在此方法中执行的逻辑无法访问用户选择的区域设置的原因。 我们在需要正确的语言环境时使用的解决方案是在包含
<f:viewAction>
@PostContruct
方法的其他支持bean中注入(CDI)
localeBean
,然后在这些方法的开头用
UIViewRoot#setLocale()
设置loc5ѭ的语言环境。     
如果您可以在您的环境中使用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);
    }
}
    

要回复问题请先登录注册