第一次设置 <f:view locale> 时 FacesContext#getViewRoot() returns null
FacesContext#getViewRoot() returns null while setting <f:view locale> for first time
我试图在一个页面中更改我的 JSF 应用程序区域设置,这必须更改我所有页面的区域设置。我已经关注了这个 link,效果很好 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 页面,我更改了 index.xhtml.
中未更改语言环境的语言环境
这是我的代码:
托管 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)
我重现了你的问题。这是自 Mojarra 2.2.5 以来应用的 issue 3021 的结果。语言环境现在在视图构建期间确定。以前,在编写您找到的答案时,语言环境是在视图呈现期间确定的,这允许代码以这种方式查找视图的默认语言环境。但是,在视图构建期间这是不可能的,因为视图尚不存在。你看,getViewRoot()
返回了 null
。
您需要改为从外部上下文获取请求区域设置。
@PostConstruct
public void init() {
locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}
您找到的答案也已更改。
我试图在一个页面中更改我的 JSF 应用程序区域设置,这必须更改我所有页面的区域设置。我已经关注了这个 link,效果很好 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 页面,我更改了 index.xhtml.
中未更改语言环境的语言环境这是我的代码:
托管 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)
我重现了你的问题。这是自 Mojarra 2.2.5 以来应用的 issue 3021 的结果。语言环境现在在视图构建期间确定。以前,在编写您找到的答案时,语言环境是在视图呈现期间确定的,这允许代码以这种方式查找视图的默认语言环境。但是,在视图构建期间这是不可能的,因为视图尚不存在。你看,getViewRoot()
返回了 null
。
您需要改为从外部上下文获取请求区域设置。
@PostConstruct
public void init() {
locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}
您找到的答案也已更改。