4 Internationalization

Web applications are frequently distributed and used on an international scale. For this reason, it’s essential that views are able to adjust dynamically to different languages and countries without having to be changed at the code level. Languages, countries and even narrower categories such as regions  can be represented by the Java type java.util.Locale.

The String representation of a locale is a well-known identifier that encodes the language and country using their standard two-character abbreviations in lower and upper case letters respectively. For example, de stands for German and DE for Germany, which means that de_DE stands for German/Germany and de_AT for German/Austria.

The string representation can be further refined by appending additional variants for regions (for example, de_DE-BW stands for German/Germany/Baden-Württemberg, a region in the southwest of Germany). In light of this, we often refer to applications, websites or individual areas of a website as being localized – that is, displayed according to the particulars of the current locale.

A number of tags can be localized in JSF by specifying a Locale object or its String representation (e.g. the displaying of dates).  If a tag does not possess explicit information about a locale, the locale of the enclosing tag will be used. If this tag also does not possess any information, the locale can be read from a browser request. The Accept-Language header on the request contains a list of accepted locales, which can be managed in the browser settings.

In addition to “localizable” tags, the automatic adjustment of texts is another important requirement. In each view, there are titles or captions that must be furnished with different content (e.g. English or German terms) depending on the respective locale. The translations are managed in the form of key-word pairs. The class java.util.ResourceBundle represents and implements this form of management. JSF applications allow us to deposit the ResourceBundle data in properties files. When the view is rendered, the text will then be read from the relevant properties file via the key and in accordance with the current locale.

The configuration file faces-config.xml, which we have already come across, can be used to determine which locales are supported by our JSF application and which ResourceBundles are available globally. Our My-Campaign application will support English and German. When the client does not explicitly supply a supported language in its HTTP request, English will be used as the default language. To implement internationalization, we will therefore introduce a ResourceBundle called messages for localizing text messages. This involves assigning a variable name msg that can be used in the Facelets’ EL expressions to acces the localized text. We can modify the file faces-config.xml according to Listing 4-1:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.2"

Listing 4-1     Configuration file faces.config.xml

As a datastore for our ResourceBundle message, we will now create a properties file for each locale in the directory src\main\resources. The file names consist of the base name messages – as specified in Listing 4-1 – plus the string representation of the respective locale and the suffix .properties.

In order to be able to try out the concept, we want to localize the title and welcome form of the welcome page index.xhtml. To do this, we will create the properties files messages_en.properties and messages_de.properties in accordance with ‎Listing 4-2 and ‎Listing 4-3. Lines that begin with # are comments. We will use the English terms as keys.

# index.xhtml
welcome.title=Workshop Java EE 7
welcome.text=Java EE 7: Welcome to our Cloud Tutorial!

Listing 4-2     Properties file messages_en.properties

# index.xhtml
welcome.title= Workshop Java EE 7
welcome.text=Java EE 7: Willkommen zu unserem Cloud Tutorial!

Listing 4-3     Properties file messages_de.properties

Hierarchical Searches in Properties Files

Often, a locale-independent properties file containing all the default texts of the application is defined. For our ResourceBundle, this would be the file with the name messages.properties. It represents the root of a search tree that will ideally store the properties files for the languages on the second level, the countries on the third level and the regionson the fourth level. The search begins in the most specialized file (i.e. the leaf of the tree) and, if unsuccessful, moves towards the root with the hopes of yielding results. For the locale de_DE, the search would begin in messages_de_DE.properties before moving to messages_de.properties and finally to messages.properties.

All that’s left to do now is to access the ResourceBundle in the Facelet index.xhtml; then, we’ll be ready attempt localization. To do this, we will replace the hard-coded texts with EL expression using the corresponding keys in the properties files. We will adjust the Facelet as shown in ‎Listing 4-4:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 	

Listing 4-4     Facelet index.xhtml

Now we restart our runner (WildFly) again to force a redeployment. After that, we can trial our whole implementation by running our browser with multiple locales. Current browsers provide extentions or add-ons that allow to switch the locale, immediately (e.g. Quick Language Switcher for Chrome). The result that appears in the browser  should vary depending on which locale has been set. Try it out and see for yourself! If you have problems so far, you can compare your current project with that provided by us at the beginning of the following chapter.


Use the message board below to give the authors your feedback or to discuss this page’s topic with other readers (in English please!). Please don’t expect the authors to answer directly, but they might update the content of this site according to your feedback.