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

JSF中的本地化,如何记住每个会话而不是每个请求/视图选择的语言环境,jsf,session,jsf-2,localization,internationalization,Jsf,Session,Jsf 2,Localization,Internationalization,faces config.xml: <application> <locale-config> <default-locale>ru</default-locale> <supported-locale>ua</supported-locale> </locale-config> </application> 问题是,uaLocale被应用,但只针对

faces config.xml

<application>
    <locale-config>
        <default-locale>ru</default-locale>
        <supported-locale>ua</supported-locale>
    </locale-config>
</application> 
问题是,
ua
Locale被应用,但只针对每个请求/视图,而不针对会话。同一会话中的另一个请求/视图将区域设置重置回默认值
ru
value


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

您需要将所选区域设置存储在会话作用域中,并在viewroot中的两个位置进行设置:一次是在更改区域设置后立即设置(这会更改当前viewroot的区域设置,从而反映在回发中;之后执行重定向时不需要此部分)和的
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>
下面是视图的一个示例:

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/Facelets i18n示例

请注意,JSF的功能不需要
,但搜索机器人如何解释您的页面是必须的。否则,它可能会被标记为重复内容,这对SEO不利

相关的:

您需要将选定的区域设置存储在会话作用域中,并在viewroot中的两个位置进行设置:更改区域设置后立即设置一次(这会更改当前viewroot的区域设置,从而反映在回发中;之后执行重定向时不需要此部分)在的
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>
下面是视图的一个示例:

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/Facelets i18n示例

请注意,JSF的功能不需要
,但搜索机器人如何解释您的页面是必须的。否则,它可能会被标记为重复内容,这对SEO不利

相关的:

    • 我发现.properties文件名也有问题。 Java语言环境us代码(小写)如:en_gb 但是自动创建的区域设置(由Netbeans创建)是小写字母,即:messages\u en\u GB.properties 将名称更改为:messages\u en\u gb.properties
      它应该可以工作-如果您尝试了所有方法,我发现问题也出在.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);
          }
      }
      

      如果可以在环境中使用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值,那么它将正常工作。我现在遇到了相同的问题,它工作正常。

      此组件f:view不存在您的JSF页面它将不工作,并且它将只显示默认的英语lish语言。为这个f:view组件提供localae值,那么它就可以正常工作了。我现在也遇到了同样的问题,因为它可以正常工作。

      对@BalusC的一点小评论是一个很好的解决方案。如果我们有
      在backingbean中执行一些方法。Locale可从调用
      FacesContext.getCurrentInstance().getViewRoot()获得.getLocale()
      该方法中的区域设置是由用户浏览器或默认应用程序区域设置的,而不是由用户选择在会话bean上设置的区域设置(当然,如果浏览器区域设置等于用户选择的区域设置,则它们可以匹配)

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

      编辑。使用后,此区域设置行为与
      无关,因为请求中的
      @postcontract
      也有类似行为(在用户选择区域设置后)在呈现响应阶段执行。
      @postcontract
      方法在调用应用程序阶段执行。这就是为什么在此方法中执行的逻辑无法访问用户选择的区域设置


      当我们需要正确的区域设置时,我们使用的解决方案是在包含
      @postcontract
      方法的其他支持bean中注入(CDI)
      localeBean
      ,然后使用
      UIViewRoot#setLocale()设置区域设置
      来自
      localeBean
      在这些方法的开头。

      对@BalusC的一个小评论是一个很好的解决方案。如果我们有
      在backbacking bean中执行一些方法。Locale可从调用
      FacesContext.getCurrentInstance().getViewRoot().getLocale()获得
      在该方法中,由用户浏览器或默认应用程序区域设置的区域设置,而不是由用户选择在会话bean上设置的区域设置(当然,如果浏览器区域设置等于用户选择的区域设置,则它们可以匹配)

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

      编辑。使用后,此区域设置行为与
      无关,因为在渲染响应阶段执行请求(在用户选择区域设置后)中的
      @postcontract
      也有类似的行为<