Localization in JSF, how to remember the selected locale per session instead of query / view

faces-config.xml :

 <application> <locale-config> <default-locale>ru</default-locale> <supported-locale>ua</supported-locale> </locale-config> </application> 

In the bean action method, I change the locale in the current view as follows:

 FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua")); 

The problem is that ua Locale is applied, but only for each request / view, and not for the session. Another request / view within the same session resets the locale to the default value ru .

How can I apply the locale for a session?

+36
internationalization session jsf jsf-2 localization
Jan 28 '11 at 16:26
source share
5 answers

You need to save the selected locale in the session area and set it in the viewing mode in two places: once UIViewRoot#setLocale() immediately after changing the locale (which changes the locale of the current viewroot and, thus, is reflected in the postback, this part is not needed when you do the redirection afterwards) and once in the locale <f:view> attribute (which sets / saves the locale in subsequent queries / views).

Here is an example of what a LocaleBean looks like:

 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); } } 

And here's an example view should look like this:

 <!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> 

Please note that <html lang> not required for JSF to function, but it is imperative that search engines interpret your page. Otherwise, it may be marked as duplicate content, which is bad for SEO.

Connected:

+72
Jan 28 2018-11-11T00:
source share

I see that the problem is also in the .properties file name. Java Locale us code (lowercase letters): en_gb But the automatically generated locale (by Netbeans) has a lowercase subprocess, that is, messages: messages_en_GB.properties Change the name to: messages_en_gb.properties and it should work - if you tried everything

+3
Nov 13 2018-11-11T00:
source share

This f: view component does not exist your JSF page, it will not work, and it will display only English by default. Specify the localae value for this f: view component, then it will work fine. Now I am facing the same problem as her work.

+2
Apr 30 '16 at 6:37
source share

One small comment on @BalusC's great solution. If we have a <f:viewAction> that executes some method with bean support. The locale accessible from the call to FacesContext.getCurrentInstance().getViewRoot().getLocale() inside this method will be the local, installed by the user's browser or the default local application language, and not the locale that is set in the bean of your choice user (of course, they can coincide if the browser language is equal to this language selected by the user).

I can handle the fix because maybe I did something wrong when implementing the solution provided by @BalusC.

EDIT. After playing with the JSF life cycle , this locale behavior is not associated with <f:viewAction> , because there is a similar behavior with @PostContruct . <f:view locale="#{localeBean.locale}"> in the request (after the locale selected by the user) is executed in the render response phase. The <f:viewAction> and @PostContruct are executed when the application phase is called. This is why the logic that runs in this method does not have access to the language selected by the user.

The solution we use when we need the right locale is to inject the (CDI) localeBean into another bean support that contains the <f:viewAction> and @PostContruct , and then set the locale with UIViewRoot#setLocale() from localeBean to beginning of these methods.

+1
Dec 23 '16 at 23:04
source share

If you can use CDI and deltaspike ( JSF module ) in your environment, you can add the following to your LocaleBean to automatically reset the locale of the current view:

 @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); } } 
0
Mar 08 '16 at 13:17
source share



All Articles