FacesContext#getViewRoot() returns null while setting <f:view locale> for first time

白昼怎懂夜的黑 提交于 2019-12-10 19:33:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!