FacesContext#getViewRoot()在第一次设置<f:view locale =“”>时返回null

时间:2015-06-04 20:53:47

标签: jsf locale jsf-2.2 mojarra

我正在尝试在一个页面中更改我的JSF应用程序区域设置,并且必须更改我的所有页面区域设置。我已按照此链接进行操作,Localization in JSF, how to remember selected locale per session instead of per request/view

效果很好

如果我运行应用程序,我可以更改 index.xhtml 中的区域设置,并且每个会话都会设置该区域设置,所以如果我转到 index_1.xhtml 页面我会看到语言环境发生了变化。

我的问题是,当我运行应用程序并编写URL:http://localhost:8080/Myapp-war/faces/index_.xhtml以转到 index_1.xhtml 页面时,我更改了区域设置未在索引中更改的区域设置.xhtml。

这是我的代码:

Managed Bean

package controllers;

import java.io.Serializable;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

    @ManagedBean
    @SessionScoped
    public class LanguageSwitcher implements Serializable{

        private Locale locale; 


        @PostConstruct
        public void init() 
        {
            locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
        }


       public Locale getLocale() {
            return locale;
        }

        public String getLanguage() {
            return locale.getLanguage();
        }

        //Change locale
        public void changeLanguage(String language) {
            locale = new Locale(language);
            FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
        }   

    }

文件index.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html   lang="#{languageSwitcher.language}"
        xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">


    <h:head>
    </h:head>

    <h:body>     
        <h3>Language switcher:</h3>
        <h:form id="language_form">
            <h:commandLink action="#{languageSwitcher.changeLanguage('es')}" value="Español" rendered="#{languageSwitcher.language != 'es'}"/> |
            <h:commandLink action="#{languageSwitcher.changeLanguage('en')}" value="English" rendered="#{languageSwitcher.language != 'en'}"/>
        </h:form>

       <h:outputText value="#{msg['greeting']}" />

    </h:body>
</html>

文件index_1.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html   lang="#{languageSwitcher.language}"
        xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

    <f:view locale="#{languageSwitcher.locale}">

    <h:head>
    </h:head>

    <h:body>     
        <h3>Language switcher:</h3>
        <h:form id="language_form">
            <h:commandLink action="#{languageSwitcher.changeLanguage('es')}" value="Español" rendered="#{languageSwitcher.language != 'es'}"/> |
            <h:commandLink action="#{languageSwitcher.changeLanguage('en')}" value="English" rendered="#{languageSwitcher.language != 'en'}"/>
        </h:form>

       <h:outputText value="#{msg['greeting']}" />

    </h:body>
  </f:view>
</html>

如果我在index.xhtml中写<f:view locale="#{languageSwitcher.locale}">,那么当我运行应用时,我会收到错误。

我怎么解决?

更新

运行应用时遇到的错误是:

显示java.lang.NullPointerException     在controllers.LanguageSwitcher.init(LanguageSwitcher.java:56)

1 个答案:

答案 0 :(得分:7)

我转载了你的问题。这是issue 3021的结果,自Mojarra 2.2.5开始应用。现在,在视图构建期间确定了区域设置。以前,在编写您找到的答案时,区域设置是在视图渲染时确定的,这允许代码以这种方式查找视图的默认区域设置。但是,在视图构建期间,这是不可能的,因为视图尚不存在。您看,getViewRoot()已返回null

您需要从外部上下文中获取请求区域设置。

@PostConstruct
public void init() {
    locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}

你找到的答案也有所改变。