A JSF application can be internationalized with standard resource bundles (java.util.ResourceBundle
) and messages. Resource bundles are suitable to internationalize the text on the components, controls, and digital assets; whereas message files are meant to internationalize the JSF validation errors.
In a Gradle or Maven project, we will add a resource bundle or message file to the src/main/resources
project location with the necessary Java package as folders.
We will configure the resource bundles in the Faces configuration file, /WEB-INF/faces-config.xml
, for the web application.
For the contact details application in Chapter 4, JSF Validation and AJAX, we have two resource bundle files in English and German: appMessages.properties
and appMessage_de.properties
respectively.
Here is the English language bundle:
// uk/co/xenonique/digital/appMessages.properties contactForm.firstName=First Name contactForm.lastName=Last Name contactForm.houseOrFlatNumber=House or Flat Number contactForm.street1=Street 1 contactForm.street2=Street 2 contactForm.townOrCity=Town or City contactForm.region=Region contactForm.postCode=Post Code
Here is the German language bundle:
// uk/co/xenonique/digital/appMessages_de.properties contactForm.firstName=Vornamen contactForm.lastName=Nachnamen contactForm.houseOrFlatNumber=Haus oder Wohnung Nummer contactForm.street1=Strasse 1 contactForm.street2=Strasse 2 contactForm.townOrCity=Stadt oder Gemeinde contactForm.region=Lande contactForm.postCode=PLZ
In order to use these bundles in our JSF bundle, we will configure the Faces configuration as follows:
<?xml version="1.0"?> <faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"> <application> <resource-bundle> <base-name>uk.co.xenonique.digital.appMessages</base-name> <var>appMessages</var> </resource-bundle> </application> </faces-config>
We will define a resource bundle configuration in /WEB-INF/faces-config.xml
for our application messages. In this file, we can define an application scope variable for our bundle, namely appMessages
.
From here, we can use the bundle with an EL syntax. Here is the code for the house number in the application:
<h:form id="yourAddressForm" styleClass="form-horizontal" p:role="form"> <div class="form-group"> <h:outputLabel for="houseOrFlatNumber" class="col-sm-3 control-label"> #{appMessages['contactForm.houseOrFlatNumber']} </h:outputLabel>... </div> ... </h:form>
As we use dots (.
) in our property name, we must use the map EL syntax so as to obtain the required message: #{appMessages['contactForm.houseOrFlatNumber']}
.
Resource bundles may also contain parameterized message properties with formatted token arguments. The token arguments are expanded during message resolution by the JSF framework or through application custom code. Here is an example of parameterized message property:
contactForm.specialNote = proctor records {0}, {1} and {2}
Then, we will use the <h:outputFormat>
tag to render the output, as follows:
<h:outputFormat value="#{appMessages['contactForm.specialNote']}"> <f:param value="first argument" /> <f:param value="second argument" /> <f:param value="third argument" /> </h:outputFormat>
The backing code in the JSF applications in general may generate messages for the output that can also be internationalized. The messages are stored in the FacesContext object. We will need to ensure that a user can see all or some of these messages. We will do this with the <h:messages>
or <h:message>
JSF tags.
In Chapter 4, JSF Validation and AJAX, we already looked at faces-config.xml
for the message bundles.
For many digital sites, the user's browser determines the locale of the website. Developers can inform JSF about the languages that are supported in an application in the /WEB/faces-config.xml file
.
Here is the setting for the contact details application:
<faces-config> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>fr</supported-locale> <supported-locale>de</supported-locale> </locale-config> </application> </faces-config>
In this file, we will specify that our default locale is English and the supported locales are French and German.
There are certain digital sites where the requirement is to allow the user to switch between two or more locales. So, we must programmatically achieve this goal. For each rendered view in JSF, we will need to set the locale in the controller method. We will use FacesContext to gain access to the root view UI in the Faces response and set the locale here.
Suppose that we are working for a sports automotive manufacturer with their offices in London, UK, and Heidelberg, Southern Germany; then, we can write the following code:
final UIViewRoot viewRoot = FacesContext .getCurrentInstance().getViewRoot(); viewRoot.setLocale(new Locale("de"));
The view will be set to the German locale.
If the stakeholder wants a digital site where each individual page may have its own configured locale, then JSF can achieve this goal. Developers can use the <f:view>
view tag to override the locale for a page. Before the JSF 2.0 standard, the view tag wrapped the content and acted as a container element. In JSF 2.0 and later versions, this is now unnecessary and the view tag can set the locale.
Here is a code extract that retrieves the locale from a user profile bean with a property called primaryLocale
:
<f:view locale="#{userProfile.primaryLocale}"/>
Here is the session-scoped bean that goes with the page view:
@SessionScoped class UserProfile { private Locale primaryLocale = Locale.ENGLISH; public Locale getPrimaryLocale() { return primaryLocale; } }