Spring 3 MVC: Internationalization & Localization Tutorial with Example

Welcome to Part 5 for Spring 3.0 MVC Series. In previous article we saw how to configure Tiles framework with Spring 3 MVC application. We used org.springframework.web.servlet.view.tiles2.TilesConfigurer class in bean definition to define the tiles configuration file. This divided our HelloWorld Spring MVC application in sections such as header, footer etc. In this part we will discuss about Internationalization (I18N) and Localization (L10N) in Spring 3.0 MVC. We will add i18n support followed by l10n to our HelloWorld Spring application that we created in previous tutorials in this series. I strongly recommend you to go through previous articles and download the source code of our sample application. [sc:SpringMVC_Tutorials]

What is i18n and L10n?

In computing, internationalization and localization are means of adapting computer software to different languages and regional differences. Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting internationalized software for a specific region or language by adding locale-specific components and translating text. The terms are frequently abbreviated to the numeronyms i18n (where 18 stands for the number of letters between the first i and last n in internationalization) and L10n respectively, due to the length of the words. The capital L in L10n helps to distinguish it from the lowercase i in i18n.

Our Goal

Our goal is to add Internationalization and Localization support to our Spring MVC application. Once finished our app will look like. We will add two languages support to our application: English and German. Depending on the locale setting of users browser, the appropriate language will be selected. Also user will be able to select the language from top-right corner of the application.

Message Resouces File

We will create two properties file which will contain all the messages to be displayed in the application. These files are kept in a source folder called “resources”. Create a source folder in your project by Right click on Project name > New > Source Folder and name it resources. Create two files messages_en.properties and messages_de.properties in this folder and copy following content into it. File: resources/messages_en.properties
label.firstname=First Name label.lastname=Last Name label.email=Email label.telephone=Telephone label.addcontact=Add Contact label.menu=Menu label.title=Contact Manager label.footer=© ViralPatel.net
Code language: HTML, XML (xml)
File: resources/messages_de.properties
label.firstname=Vorname label.lastname=Familiename label.email=Email label.telephone=Telefon label.addcontact=Addieren Kontakt label.title=Kontakt Manager label.menu=Menü label.footer=© ViralPatel.net
Code language: HTML, XML (xml)

Configuring Internationalization (i18n) / Localization (L10n) in Spring MVC

Now we have created message resource properties for our application. We need to declare these files in spring configuration file. We will use class org.springframework.context.support.ReloadableResourceBundleMessageSource to define the message resources. Also, note that we will provide a feature where user will be able to select language for the application. This is implemented by using org.springframework.web.servlet.i18n.LocaleChangeInterceptor class. The LocaleChangeInterceptor class will intercept any changes in the locale. These changes are then saved in cookies for future request. org.springframework.web.servlet.i18n.CookieLocaleResolver class will be used to store the locale changes in cookies. Add following code in the spring-servlet.xml file. File:WebContent/WEB-INF/spring-servlet.xml
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:messages" /> <property name="defaultEncoding" value="UTF-8"/> </bean> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"> <property name="paramName" value="lang" /> </bean> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="defaultLocale" value="en"/> </bean> <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <ref bean="localeChangeInterceptor" /> </property> </bean>
Code language: HTML, XML (xml)
Note that in above configuration we have defined basename property in messageSource bean to classpath:messages. By this, spring will identify that the message resource message_ will be used in this application.

Change the View – The JSPs

Now as we have created two message resources files and configured it in Spring MVC, we will use these messages in the JSP files. Open all the JSP files of our demo application and update with following code. File:WebContent/WEB-INF/jsp/header.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <h3><spring:message code="label.title"/></h3> <span style="float: right"> <a href="?lang=en">en</a> | <a href="?lang=de">de</a> </span>
Code language: HTML, XML (xml)
File:WebContent/WEB-INF/jsp/menu.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <p><spring:message code="label.menu"/></p>
Code language: HTML, XML (xml)
File:WebContent/WEB-INF/jsp/footer.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <spring:message code="label.footer"/>
Code language: HTML, XML (xml)
File:WebContent/WEB-INF/jsp/contact.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <title>Spring 3 MVC Series - Contact Manager</title> </head> <body> <form:form method="post" action="addContact.html"> <table> <tr> <td><form:label path="firstname"><spring:message code="label.firstname"/></form:label></td> <td><form:input path="firstname" /></td> </tr> <tr> <td><form:label path="lastname"><spring:message code="label.lastname"/></form:label></td> <td><form:input path="lastname" /></td> </tr> <tr> <td><form:label path="lastname"><spring:message code="label.email"/></form:label></td> <td><form:input path="email" /></td> </tr> <tr> <td><form:label path="lastname"><spring:message code="label.telephone"/></form:label></td> <td><form:input path="telephone" /></td> </tr> <tr> <td colspan="2"> <input type="submit" value="<spring:message code="label.addcontact"/>"/> </td> </tr> </table> </form:form> </body> </html>
Code language: HTML, XML (xml)
Note that in above JSP, we used <spring:message> tag to display the message from resource bundle. One thing that we must note here is that in header.jsp file, we have specified two links to select language. The link sets a request parameter ?lang= when user click on this link. Note that spring identifies this request parameter by using LocaleChangeInterceptor interceptor and change the local accordingly. Also note that while configuring LocaleChangeInterceptor in spring-servlet.xml file, we have specified property “paramName” with value “lang”
<property name="paramName" value="lang" />
Code language: HTML, XML (xml)
Thus the Spring framework will look for a parameter called “lang” from request.

That’s All Folks

That’s pretty much it :) We just added Internationalization and Localization support to our demo Spring 3.0 MVC application. All you have to do is just execute the app in Eclipse. Press Alt + Shift + X, R.

Download Source Code

Click here to download Source Code (10.2kb)

Moving On

Today we saw how to add Internationalization i18n and Localization L10n support to Spring 3.0 based web application. We used LocaleChangeInterceptor to intercept the change in locale and ReloadableResourceBundleMessageSource class to add message resources properties. In the next part we will discuss Themes in Spring MVC and how to implement it. I hope you liked this article. Feel free to post your queries and comments in comment section.

View Comments

  • I have a queston. You defined two languages, and de. What if a visitor comes who is from let's say Canada. Which locale will be chosen for him as default? Is there a way to specify a default locale at all?

    • @mateusz f. nice question. There is a way in spring to define default local. This can be done by passing parameter defaultLocale to CookieLocaleResolver bean.
      [code language="xml"]
      <bean id="localeResolver"
      class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
      <property name="defaultLocale" value="en"/>
      </bean>
      [/code]

  • Thanks very much for the sample.

    Only question so far is that when I run mvn tomcat:redeploy it looks for mvc-basic-1.0.0-SNAPSHOT.war rather than mvc-basic.war that the install actually builds

  • Hi Viral, nice tutorial.
    I am experiencing problems. I have followed your example and used two languajes, spanish and english. If I set the defaultLocale to 'en' all the page is visible on english no matter the spanish accept of the navigator. It is as if it setted how the page should be viewed as default unless the user specifies something different. Do you know if it can be used so the page is viewed in spanish if the navigator is set to spanish and to english otherwise?
    Setting the defaultLocale solved the problem of other navigators with another languaje setted.

    Thank

  • Hi Viral, I finally managed to solve the problem by extending the SessionLocaleResolver, overriding the determineDefaultLocale and injecting the supported languajes to the new resolver. It may sound a little complicated but it was not too much and now works like a charm.

    Thank you for the basis.

Share
Published by
Viral Patel
Tags: internationalization Spring spring mvc spring-3-mvc-series

Recent Posts

  • Java

Java URL Encoder/Decoder Example

Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…

4 years ago
  • General

How to Show Multiple Examples in OpenAPI Spec

Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…

4 years ago
  • General

How to Run Local WordPress using Docker

Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…

5 years ago
  • Java

Create and Validate JWT Token in Java using JJWT

1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…

5 years ago
  • Spring Boot

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…

5 years ago
  • Spring Boot

Spring Boot DynamoDB Integration Test using Testcontainers

1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…

5 years ago