Pages

2014-06-14

Java EE (JSF): Internationalization and localization

Configuring locales:

The first step toward supporting multiple languages is to tell your JSF application which locales it should support. You specify the supported locales with the <locale-config> element in a Faces configuration file, under the <application> node:

<application>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
<supported-locale>es</supported-locale>
</locale-config>
<message-bundle>CustomMessages</message-bundle>
</application>
The letters “en” and “es” stand for English and Spanish, respectively. So this tells our application to support both English and Spanish, and to use English as the default.

Creating resource bundles:

Once you’ve configured your JSF application to support different locales, you have to place locale-specific versions of your application’s text strings in resource bundles. Resource bundles aren’t a JSF feature—they’re a fundamental part of the way Java handles internationalization and localization.

LocalizaitonResources_en.properties:
numberOfVisits=You have visited us {0} time(s), {1}. Rock on!
toggleLocale=Translate to Spanish
helloImage=../images/hello.gif
After you have created a localized properties filelanguage), you must convert it to use Unicode characters. This can be done with the native2ascii tool included with the Java Development Kit (JDK). 

Using resource bundles with components:

Using a resource bundle in a JSF application is as simple as using a value-binding expression. All you have to do is load the proper resource bundle and make it accessible in an application scope. For JSP, there’s a JSF core tag, <f:loadBundle>, that loads the bundle and stores it in the request scope automatically.Here’s how
you use it:
<f:loadBundle basename="LocalizationResources" var="bundle"/>
The basename attribute specifies the name of the resource bundle, prefixed by its location in your classpath. Because our bundles were placed in WEB-INF/classes, no prefix is needed. However, if we had nested them deeper, like in the WEB-INF/classes/org/jia directory, the basename would be "org.jia.LocalizationResources".

We can access value of the key numberOfVisits, with the value-binding expression "#{bundle.halloween}".

2014-06-13

Java EE (JSF): Initializing List and Array properties for Managed Beans

If you have a property that is an array or a List, you can initialize it with default values. If the property is set to null, the facility will create a new List or array and initialize it for you. If it’s non-null, the facility will simply add any values you define to the existing collection.

Instead of specifying a single value for the property, you specify multiple values. You can configure a List or array property by nesting <value> or <null-value> elements inside a <list-entries> element, which is a child of the <managed-property> element.

Let’s say our UserBean class also has a favoriteSites property, which is a List of Strings representing the user’s favorite sites. If we wanted to provide a default list of values for the favoriteSites property, we could define it like so:

<managed-bean><managed-bean-name>user</managed-bean-name><managed-bean-class>org.jia.examples.UserBean</managed-bean-class><managed-bean-scope>request</managed-bean-scope>...<managed-property><property-name>favoriteSites</property-name><list-entries><value>http://www.jsfcentral.com</value><value>http://www.theserverside.com</value><value>http://www.ibm.com/developerworks/</value><value>http://otn.oracle.com</value><value>http://www.java.net</value><value>http://www.manning.com</value></list-entries></managed-property>...</managed-bean>

In the previous example, all values were stored as String objects, which is the default. If you want all of the values to be converted to a specific type, you can use the <value-class> attribute. Here’s a List property whose values are all Integers:

<managed-bean>...<managed-property><property-name>favoriteNumbers</property-name><list-entries><value-class>java.lang.Integer</value-class><value>31415</value><value>278</value><value>304</value><value>18</value><value>811</value><value>914</value></list-entries></managed-property>...</managed-bean>