When you implement a web application, it is a good idea to collect all message strings in a central location. This process makes it easier to keep messages consistent and, crucially, makes it easier to localize your application for other locales JSF simplifies this process. First, you collect your message strings in a file in the time-honored "properties" format: currentScore=Your current score is: guessNext=Guess the next number in the sequence! NOTE | Look into the API documentation of the load method of the java.util.Properties class for a precise description of the file format. |
Save the file together with your classes, for example, in WEB-INF/classes/com/corejsf/messages.properties. You can choose any directory path and file name, but you must use the extension .properties. Add the f:loadBundle element to your JSF page, like this: <f:loadBundle basename="com.corejsf.messages" var="msgs"/> This element loads the messages in the bundle into a map variable with the name msgs, and stores that variable in request scope. (The base name looks like a class name, and indeed the properties file is loaded by the class loader.) You can now use value binding expressions to access the message strings: <h:outputText value="#{msgs.guessNext}"/> That's all there is to it! When you are ready to localize your application for another locale, you simply supply localized bundle files. When you localize a bundle file, you need to add a locale suffix to the file name: an underscore followed by the lowercase two-letter ISO-639 language code. For example, German strings would be in com/corejsf/messages_de.properties. NOTE | You can find a listing of all two- and three-letter ISO-639 language codes at http://www.loc.gov/standards/iso639-2/. |
As part of the internationalization support in Java, the bundle that matches the current locale is automatically loaded. The default bundle without a locale prefix is used as a fallback when the appropriate localized bundle is not available. (See Chapter 10 of Horstmann & Cornell, Core Java vol. 2 for a detailed description of Java internationalization.) NOTE | When you prepare translations, keep one oddity in mind: message bundle files are not encoded in UTF-8. Instead, Unicode characters beyond 127 are encoded as \uxxxx escape sequences. The Java SDK utility native2ascii can create these files. |
You can have multiple bundles for a particular locale. For example, you may want to have separate bundles for commonly used error messages. Once you have prepared your message bundles, you need to decide how to set the locale of your application. You have three choices: You can add a locale attribute to the f:view element, for example, <f:view locale="de"> You can set the default and supported locales in WEB-INF/faces-config.xml (or another application configuration resource): <faces-config> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>de</supported-locale> </locale-config> </application> </faces-config> When a browser connects to your application, it usually includes an Accept-Language value in the HTTP header (see http://www.w3.org/International/questions/qa-accept-lang-locales.html). JSF reads the header and finds the best match among the supported locales. You can test this feature by setting the preferred language in your browser see Figure 2-2. Figure 2-2. Selecting the Preferred Language
You can call the setLocale method of the UIViewRoot object: UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot(); viewRoot.setLocale(new Locale("de")); See chapter 7 for more information. |