Home  >  Q&A  >  body text

How to implement session level localization in JSF instead of per request/view level selected locale memorization

<p><code>faces-config.xml</code>:</p> <pre class="brush:php;toolbar:false;"><application> <locale-config> <default-locale>ru</default-locale> <supported-locale>ua</supported-locale> </locale-config> </application></pre> <p>In a bean action method, I change the locale of the current view as follows: </p> <pre class="brush:php;toolbar:false;">FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale("ua"));</pre> <p>The problem is that the <code>ua</code> locale only applies to requests/views, not sessions. Another request/view in the same session will reset the locale to the default <code>ru</code> value. </p> <p>How do I apply a locale to a session? </p>
P粉360266095P粉360266095424 days ago473

reply all(2)I'll reply

  • P粉662802882

    P粉6628028822023-08-23 10:48:27

    I see that the problem is also related to the .properties file name. Java's Locale code (lowercase) such as: en_gb But the Locale automatically generated by Netbeans is lowercase_uppercase, for example: messages_en_GB.properties Change it to: messages_en_gb.properties Then it should work fine - if you've tried everything

    reply
    0
  • P粉426906369

    P粉4269063692023-08-23 00:27:17

    You need to store the selected locale in session scope and set it in two places: once via UIViewRoot#setLocale() Immediately after changing the locale (This will change the locale of the current view root so that it is reflected in subsequent requests; if you perform a redirect later, this part is unnecessary), and once in <f:view> in the locale attribute (this will set/preserve the locale on subsequent requests/views).

    Here is an example of how LocaleBean should look:

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

    This is an example of how the view should look:

    <!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 示例</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>

    This assumes that #{text} has been configured in faces-config.xml as follows:

    <application>
        <resource-bundle>
            <base-name>com.example.i18n.text</base-name>
            <var>text</var>
        </resource-bundle>
    </application>

    Please note that <html lang> is not required for JSF functionality, but is mandatory for search engine explanation pages. Otherwise, it may be marked as duplicate content, which is bad for SEO.

    See also:

    reply
    0
  • Cancelreply