Technically we can add support for as many languages as we want with
internationalization, but for demonstration purposes I am going to show you how to make our add products page with Dutch language support:
Create a file called messages_nl.properties under /src/main/resources in
1. your project, add the following lines in it, and save the file:
addProduct.form.productId.label = Nieuw product ID
addProduct.form.name.label = Naam
addProduct.form.unitPrice.label = prijs per eenheid
addProduct.form.manufacturer.label = fabrikant
addProduct.form.category.label = categorie
addProduct.form.unitsInStock.label = Aantal op voorraad
addProduct.form.description.label = Beschrijving
addProduct.form.condition.label = Product Staat
addProduct.form.productImage.label = product afbeelding
Internalize Your Store with Interceptor
Open our addProduct.jsp and add the following set of tags right after the
2. <body> tag:
<section>
<div class="pull-right" style="padding-right:50px">
<a href="?language=en" >English</a>|<a href="?
language=nl" >Dutch</a>
</div>
</section>
Now open our web application context configuration file,
3.
WebApplicationContextConfig.java, and add one more bean definition for the locale resolver as follows:
@Bean
public LocaleResolver localeResolver(){
SessionLocaleResolver resolver = new
SessionLocaleResolver();
resolver.setDefaultLocale(new Locale("en"));
return resolver;
}
Now change our addInterceptors method to configure one more interceptor in
4. our InterceptorRegistry as follows:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new
ProcessingTimeLogInterceptor());
LocaleChangeInterceptor localeChangeInterceptor = new
LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
registry.addInterceptor(localeChangeInterceptor);
}
Internalize Your Store with Interceptor
[ 164 ]
Now run our application and enter the
5. http://localhost:8080/webstore/market/products/add URL; you will
be able to see our regular add products page with two extra links in the top-right corner to choose the language:
The add products page showing internationalization support to choose languages
Now click on the Dutch link; you will see the product ID label transformed into
6. the Dutch caption Nieuw product ID.
Since our configured LocaleChangeInterceptor will add a request parameter
7. called language to the web request, we need to add this language request parameter to our whitelisting set in our ProductController. Open our
ProductController and, within the initialiseBinder method, add the language request parameter to the whitelisting set as follows:
binder.setAllowedFields("productId",
Internalize Your Store with Interceptor
"name",
"unitPrice",
"description",
"manufacturer",
"category",
"unitsInStock",
"condition",
"productImage",
"language");
What just happened?
In step 1, we just created a property file called messages_nl.properties. This file acts as
a Dutch-based message source for all our externalized label messages in the
addProducts.jsp file. In order to display the externalized label messages, we used the
<spring:message> tag in our addProducts.jsp file.
But by default, the <spring:message> tag will read messages from the
messages.properties file only; we need to make a provision for our end user to switch to the Dutch locale when they view the webpage, so that the label messages can come from the messages_nl.properties file. We provided such a provision through a locale-choosing link in addProducts.jsp, as mentioned in step 2:
<a href="?language=en" >English</a>|<a href="?language=nl" >Dutch</a>
In step 2, we created two links, one each to choose English or Dutch as the preferred locale. When the user clicks on one of these links, it will add a request parameter called language
to the URL with the corresponding locale value. For example, when we click on the English link on the add products page at runtime, it will change the request URL
to http://localhost:8080/webstore/products/add?language=en; similarly if you click on the Dutch link, it will change the request URL
to http://localhost:8080/webstore/products/add?language=nl.
In step 3, we created a SessionLocaleResolver bean in our web application context as follows:
@Bean
public LocaleResolver localeResolver(){
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(new Locale("en"));
return resolver;
}
Internalize Your Store with Interceptor
[ 166 ]
SessionLocaleResolver is the one that sets the locale attribute in the user's session. One important property of SessionLocaleResolver is defaultLocale. We assigned en as the value for the default locale, which indicates that by default our page should use English
as its default locale.
In step 4, we created a LocaleChangeInterceptor bean and configured it in the existing interceptor list:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ProcessingTimeLogInterceptor());
LocaleChangeInterceptor localeChangeInterceptor = new
LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
registry.addInterceptor(localeChangeInterceptor);
}
We assigned the string language as the value for the paramName property in
LocaleChangeInterceptor. There is a reason for this because, if you notice, in step 2 when we created the locale choosing link in add products page (addProduct.jsp), we used the same parameter name as the request parameter within the <a> tag:
<a href="?language=en" >English</a>|<a href="?language=nl" >Dutch</a>
This way we can give a hint to LocaleChangeInterceptor to choose the correct user- preferred locale. So whatever parameter name you plan to use in your URL, use the same name as the value for the paramName property in LocaleChangeInterceptor. One more thing: whatever value you have given to the language request parameter in the link should match the translation message source file suffix. For example, in our case we have created a Dutch translation message source file, messages_nl.properties; here the suffix is nl and messages.properties without any suffix is considered the default for the en suffix. That's why in step 2 we have given nl and en as the values for the language parameters for Dutch and English, respectively:
<a href="?language=en" >English</a>|<a href="?language=nl" >Dutch</a>
So finally, when we run our application and enter the
http://localhost:8080/webstore/market/products/add URL, you will see our regular add products page with two extra links in the top-right corner to choose the
language.
Internalize Your Store with Interceptor
Clicking on Dutch changes the request URL
to http://localhost:8080/webstore/market/products/add?language=nl, which brings up the LocaleChangeInterceptor and reads the Dutch-based label messages from messages_nl.properties.
Note that, if we do not give a language parameter in our URL, Spring will use the default message source file (messages.properties) for translation; if we give a language
parameter, Spring will use that parameter value as the suffix to identify the correct
language message source file (messages_nl.properties).