2017  Kodetalk | Feedback | Privacy Policy | Terms | About
userimage

how to use local or localization in jsf

how to use local or localization in jsf
userimage

To internationalize your (web)application, the normal approach is to use the ResourceBundle API in combination with properties files which contains externalized text and the ResourceBundle API will load the proper text based on the current Locale and the default (fallback) locale. It sounds nicer than it actually is. Deep under the covers, the ResourceBundle API uses Properties#load(InputStream) method to load the properties files. This method uses by default the ISO-8859-1 encoding. This is explicitly mentioned in its javadoc as well. Here’s an extract of relevance:

The load(InputStream) / store(OutputStream, String) methods work the same way as the load(Reader)/store(Writer, String) pair, except the input/output stream is encoded in ISO 8859-1 character encoding. Characters that cannot be directly represented in this encoding can be written using Unicode escapes ; only a single ‘u’ character is allowed in an escape sequence. The native2ascii tool can be used to convert property files to and from other character encodings.

Find the complete example here,


package com.kodetalk.faces.i18n;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public class Text extends ResourceBundle {

    protected static final String BUNDLE_NAME = "com.kodetalk.faces.i18n.text";
    protected static final String BUNDLE_EXTENSION = "properties";
    protected static final Control UTF8_CONTROL = new UTF8Control();

    public Text() {
        setParent(ResourceBundle.getBundle(BUNDLE_NAME,
            FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
    }

    @Override
    protected Object handleGetObject(String key) {
        return parent.getObject(key);
    }

    @Override
    public Enumeration getKeys() {
        return parent.getKeys();
    }


Using it in JSF is extraordinary simple: just define the fully qualified classname instead of the fully qualified bundle name as resource-bundle base-name in faces-config.xml:

    <application>
        <locale-config>
            <default-locale>en</default-locale>
            <supported-locale>nl</supported-locale>
            <supported-locale>es</supported-locale>
        </locale-config>
        <resource-bundle>
            <base-name>com.kodetalk.faces.i18n.Text</base-name>
            <var>text</var>
        </resource-bundle>
    </application>


Note the var element. This enables you to reference the bundle as #{text} without the need for f:loadBundle tag in every view.

This way you can keep your properties files UTF-8 all the way. In the above code example, their location is definied by the BUNDLE_NAME constant in the Text class. It expects them to be inside the com.example.faces.i18n package with the filenames text.properties (for generic content, this file is mandatory anyway), text_en.properties (for English), text_nl.properties (for Dutch) and text_es.properties (for Spanish).

Changing the locale in JSF/Facelets

As an extra bonus, here’s some code which shows at its simplest way how you could change the locale (actually, the language) from in the view side. It’s targeted on JSF 2.x / Facelets, but can be done as good on JSF 1.x and/or JSP with minor changes.

The view:

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


The bean:

package com.kodetalk.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 = FacesContext.getCurrentInstance().getViewRoot().getLocale();

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void setLanguage(String language) {
        this.locale = new Locale(language);
    }

}

Answer is