问题
I am trying to change my JSF application locale in one page and that has to change all my pages locale. I have followed this link, and it works well Localization in JSF, how to remember selected locale per session instead of per request/view
If I run the application I can change the locale in my index.xhtml and that locale is set per session, so if then I go to page index_1.xhtml I will see the locale changed.
My problem is that when I run the application and I write the URL: http://localhost:8080/Myapp-war/faces/index_.xhtml to go to the index_1.xhtml page and I change the locale that locale is not changed in index.xhtml.
This is my code:
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);
}
}
File 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>
File 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>
If I write <f:view locale="#{languageSwitcher.locale}">
in my index.xhtml, when I run the app I get an error.
How could I solve it?
UPDATE:
The error I get when running the app is:
java.lang.NullPointerException at controllers.LanguageSwitcher.init(LanguageSwitcher.java:56)
回答1:
I reproduced your problem. This is the consequence of issue 3021 which was applied since Mojarra 2.2.5. The locale is now determined during view build time. Previously, at time of writing the answer you found, the locale was determined during view render time which allowed the code to find view's default locale this way. However, during view build time this is not possible as the view doesn't exist yet. You see, the getViewRoot()
returned null
.
You need to obtain the request locale from the external context instead.
@PostConstruct
public void init() {
locale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
}
The answer you found has also been altered.
来源:https://stackoverflow.com/questions/30653945/facescontextgetviewroot-returns-null-while-setting-fview-locale-for-first