JSF中的本地化,如何记住每个会话而不是每个请求/视图选择的语言环境

JSF中的本地化,如何记住每个会话而不是每个请求/视图选择的语言环境,jsf,session,jsf-2,localization,internationalization,Jsf,Session,Jsf 2,Localization,Internationalization,faces-config.xml: 问题是应用了ua语言环境,但仅针对每个请求/视图,而不针对会话。同一会话中的另一个请求/视图将区域设置重置回默认ru值 如何为会话应用区域设置?您需要将所选区域设置存储在会话作用域中,并在viewroot中的两个位置设置它:一次是在更改区域设置后立即更改当前viewroot的区域设置,从而在回发中反映出来;当您在随后的请求/视图中设置/保留区域设置的区域设置属性中执行重定向时,不需要此部分 下面是这样一个LocaleBean的示例: package com.e

faces-config.xml:

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


如何为会话应用区域设置?

您需要将所选区域设置存储在会话作用域中,并在viewroot中的两个位置设置它:一次是在更改区域设置后立即更改当前viewroot的区域设置,从而在回发中反映出来;当您在随后的请求/视图中设置/保留区域设置的区域设置属性中执行重定向时,不需要此部分

下面是这样一个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>
下面是视图的一个示例:

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的功能不需要这样做,但搜索机器人如何解释页面是必须的。否则,它可能会被标记为重复的内容,这是不利于搜索引擎优化

相关的:
我发现问题也出在.properties文件名上。 Java语言环境us代码小写,如:en_gb 但是Netbeans自动创建的区域设置是小写字母,即:messages\u en\u GB.properties 将名称更改为:messages\u en\u gb.properties
而且它应该可以工作-如果您尝试了所有方法

如果您可以在环境中使用CDI和deltaspike,您可以将以下内容添加到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);
    }
}

此组件f:view不在您的JSF页面中,它将不工作,并且只显示默认的英语语言。请为此f:view组件提供localae值,然后它将正常工作。我现在也遇到了同样的问题,它工作得很好。

对@BalusC great solution说一句话。如果我们有哪一个在支持bean中执行某个方法。通过调用FacesContext.getCurrentInstance.getViewRoot.getLocale在该方法中可用的区域设置将是由用户浏览器或默认应用程序区域设置的区域设置,而不是由用户选择在会话bean上设置的区域设置。当然,如果浏览器区域设置等于用户选择的区域设置,则它们可以匹配

我可以接受纠正,因为在实现@BalusC提供的解决方案时,可能我做错了什么

编辑。玩过之后,这种行为与locale无关,因为@postcontuct也有类似的行为。在requestafter中,在呈现响应阶段执行用户选择的区域设置。和@postcontract方法在调用应用程序阶段执行。这就是为什么在此方法中执行的逻辑不能访问用户选择的区域设置


当我们需要正确的语言环境时,我们使用的解决方案是在包含和@PostContract方法的其他支持bean中注入CDI localeBean,然后在这些方法的开头使用localeBean中的UIViewRootsetLocale设置语言环境。

我很好奇,这种设置语言的技术多久使用一次?我所有的浏览器都是英文的,这是i18n技术的可靠版本吗?f:view不应该放在body标签里面吗?@Kemoda:你的选择。封面下是根组件UIViewRoot中go的属性。@BalusC,你能修复你主要文章中的代码吗?人们一次又一次地“踩在耙子上”,尤其是没有经验的程序员。谢谢。@BalusC,还有一个问题。是否必须以这种方式编辑faces-config.xml@MestreLion:参见答案的第一段。这取决于是重用视图还是重新创建视图。如果重用视图,则需要在视图上手动设置它。如果您重新创建视图,那么它将自动从bean中获取它。这是一条注释,而不是答案!请获得足够的声誉并对答案进行评论。@Kukeltje可能你是对的,但当我获得足够的声誉时,我可能会忘记这个问题。从另一方面和您使用Jsf的经验来看,您可以验证我在这里提到的f:viewAction是否存在任何问题。