Nearby lessons

29 of 35

Spring - Internationalization (I18N)

📌 What You Will Learn
  • Resolve and remember a user's locale across requests
  • Let the user change language with a request parameter
  • Move all display text into per-locale properties files and read it from a JSP

Serving the same application in more than one language. SessionLocaleResolver to remember the user's locale, LocaleChangeInterceptor to switch it from a link, and ResourceBundleMessageSource to pull every label out of a properties file.

Internationalization[I18N]

Internationalization is the process of designing Java application on the basis of Locality is called as Internationalization.

Java is providing very good Internationalization support in Java applications due to UNICODE representations and the predefined library like java.util.Locale and some of the predefined classes from java.text package.

To provide Internationalization in Spring WEB MVC applications , Spring has provided very good environment with the following two beans.

  • SessionLocaleResolver
  • LocaleChangeInterceptor

SessionLocaleResolver

SessionLocaleResolver resolves locales by inspecting a predefined attribute in a user‘s session. If the session attribute doesn‘t exist, this locale resolver determines the default locale from the accept-language HTTP header. <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">

<property name="defaultLocale" value="en" /> </bean>

LocaleChangeInterceptor

LocaleChangeInterceptor interceptor detects if a special parameter is present in the current HTTP request. The parameter name can be customized with the paramName property of this interceptor. If such a parameter is present in the current request, this interceptor changes the user‘s locale according to the parameter value.

<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" /> </bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors"> <list> <ref bean="localeChangeInterceptor" /> </list>
</property> </bean> To implement Internationalization in Spring WEB MVC application then we have to use the following steps.
  • Prepare properties file for each and every local to which we want to support.

In Internationalization , we have to prepare a seperate properties file with the locale respective messages in the form of Key-Value pairs, where keys must be in English and the values must be in the respective language letters in the form of UNOCODE.

In general, the name format of the properties file is "baseName_lang.properties".

EX:

messages_en.properties

uname = User Name upwd = User Password

messages_it.properties

uname = Usere Nameo upwd = Usere Passwordo

Prepare User forms by getting messages from the properties file — registrationform.jsp

To get messages from properties files we have to use the following tag from Spring tag library with the URI "http://www.springframework.org/tags".

<spring:message code="--"/> Where code attribute will take key of the message defined in properties file.
Example04
JCode Cell
1 
2<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
3<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
4<html>
5<body>
6<form:form method="POST" action="reg" commandName="user">
7<center>
8<table>
9<tr>
10<td><spring:message code="uname"/></td>
11<td><form:input path="uname"/></td>
12</tr>
13<tr>
14<td><spring:message code="upwd"/></td>
15<td><form:password path="upwd"/></td>
16</tr>
17<tr>
18<td><spring:message code="uemail"/></td>
19<td><form:input path="uemail"/></td>
20</tr>
21<tr>
22<td><spring:message code="umobile"/></td>
23<td><form:input path="umobile"/></td>
24</tr>
25<tr>
26<td><input type="submit" value="Registration"/></td>
27</tr>
28</table>
29</center>
30</form:form>
31</body>
32</html>
33

Prepare User forms by getting messages from the properties file

  • Configure "SessionLocaleResolver", "LocaleChangeInterceptor" and

"ResourceBundleMessageSource" in Spring Configuration File — ds-servlet.xml

Where the purpose of SessionLocaleResolver is to resolves locales by inspecting a predefined attribute in a user‘s session. If the session attribute doesn‘t exist, this locale resolver determines the default locale from the accept-language HTTP header.

Where the purpose of "LocaleChangeInterceptor" is to detects if a special parameter is present in the current HTTP request. The parameter name can be customized with the paramName property of this interceptor. If such a parameter is present in the current request, this interceptor changes the user‘s locale according to the parameter value.

Where the purpose of "ResourceBundleMessageSource" is to resolve the properties file on the basis of the provided "basename" property inorder to submit values to the User forms.

Example06
JCode Cell
1 
2<beans>
3<context:component-scan base-package="com.durgasoft" />
4<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
5 
6<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
7 <property name="prefix" value="/WEB-INF/views/" />
8 <property name="suffix" value=".jsp" />
9</bean>
10 
11<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
12<property name="basename" value="messages" />
13</bean>
14 
15<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
16<property name="defaultLocale" value="en" />
17</bean>
18 
19<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
20<property name="paramName" value="lang" />
21</bean>
22<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
23<property name="interceptors">
24 <list>
25 <ref bean="localeChangeInterceptor" />
26 </list>
27</property>
28</bean>
29 
30</beans>
31

"ResourceBundleMessageSource" in Spring Configuration File — index.jsp

Example:

messages_en.properties

title1 = Durga Software Solutions title2 = User Registration Form uname = User Name upwd = User Password uemail = User Email Id umobile = User Mobile No

messages_it.properties

title1 = Durga Software Solutions title2 = Usere Registratione Formo uname = Usero Nameo upwd = Passwordo uemail = Usere Emailo umobile = Usero Mobileo

messages_hi.properties

title1 = Durga Software Solutions title2 = User Registration Form uname = Upayuktha Naam upwd = Upayuktha Rahsya Naam uemail = Upayuktha Vidyuth Naam umobile = Upayuktha Charavani Sakya

Example07
JCode Cell
1 
2<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
3pageEncoding="ISO-8859-1"%>
4<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
5<html>
6<head>
7<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
8<title>Insert title here</title>
9</head>
10<body>
11<center>
12<h2 style="color: red;" align="center">User Registration Form</h2>
13<h3>
14<a href="/i18napp/reg?lang=en">English</a>|<a href="/i18napp/reg?lang=it">Italian</a>|<ahref="/i18napp/reg?lang=hi">Hindi</a>
15</h3>
16</center>
17</body>
18</html>
19

"ResourceBundleMessageSource" in Spring Configuration File — registrationform.jsp

Example08
JCode Cell
1 
2<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
3pageEncoding="ISO-8859-1"%>
4<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
5<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
6<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
7<html>
8<head>
9<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
10<title>Insert title here</title>
11</head>
12<body>
13<h2 style="color: red;" align="center">
14<spring:message code="title1"/>
15</h2>
16<h3 style="color: blue;" align="center">
17<spring:message code="title2"/>
18</h3>
19<form:form method="POST" action="reg" commandName="user">
20<center>
21<table>
22<tr>
23<td><spring:message code="uname"/></td>
24<td><form:input path="uname"/></td>
25</tr>
26<tr>
27<td><spring:message code="upwd"/></td>
28<td><form:password path="upwd"/></td>
29</tr>
30<tr>
31<td><spring:message code="uemail"/></td>
32<td><form:input path="uemail"/></td>
33</tr>
34<tr>
35<td><spring:message code="umobile"/></td>
36<td><form:input path="umobile"/></td>
37</tr>
38<tr>
39<td><input type="submit" value="Registration"/></td>
40</tr>
41</table>
42</center>
43</form:form>
44</body>
45</html>
46

"ResourceBundleMessageSource" in Spring Configuration File — registrationdetails.jsp

Example09
JCode Cell
1 
2<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
3pageEncoding="ISO-8859-1"%>
4<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
5<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
6<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
7<html>
8<head>
9<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
10<title>Insert title here</title>
11</head>
12<body>
13<h2 style="color: red;" align="center">
14<spring:message code="title1"/>
15</h2>
16<h3 style="color: blue;" align="center">
17<spring:message code="title2"/>
18</h3>
19<center>
20<table border="1">
21<tr>
22<td><spring:message code="uname"/></td>
23<td>${user.uname}</td>
24</tr>
25<tr>
26<td><spring:message code="upwd"/></td>
27<td>${user.upwd}</td>
28</tr>
29<tr>
30<td><spring:message code="uemail"/></td>
31<td>${user.uemail}</td>
32</tr>
33<tr>
34<td><spring:message code="umobile"/></td>
35<td>${user.umobile}</td>
36</tr>
37</table>
38</center>
39</body>
40</html>
41

"ResourceBundleMessageSource" in Spring Configuration File — I18NController.java

Example10
JCode Cell
1 
2package com.durgasoft.controller;
3 
4import org.springframework.stereotype.Controller;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RequestMethod;
7import org.springframework.web.servlet.ModelAndView;
8import com.durgasoft.command.User;
9 
10@Controller
11public class I18nController {
12@RequestMapping(value="/reg", method=RequestMethod.GET)
13public ModelAndView showForm() {
14return new ModelAndView("registrationform", "user", new User());
15}
16 
17@RequestMapping(value="/reg", method=RequestMethod.POST)
18public ModelAndView registration(User user) {
19return new ModelAndView("registrationdetails", "user", user);
20}
21}
22

"ResourceBundleMessageSource" in Spring Configuration File — User.java

Example11
JCode Cell
1 
2package com.durgasoft.command;
3 
4public class User {
5private String uname;
6private String upwd;
7private String uemail;
8private String umobile;
9 
10public String getUname() {
11return uname;
12}
13public void setUname(String uname) {
14this.uname = uname;
15}
16public String getUpwd() {
17return upwd;
18}
19public void setUpwd(String upwd) {
20this.upwd = upwd;
21}
22public String getUemail() {
23return uemail;
24}
25public void setUemail(String uemail) {
26this.uemail = uemail;
27}
28public String getUmobile() {
29return umobile;
30}
31public void setUmobile(String umobile) {
32this.umobile = umobile;
33}
34}
35

"ResourceBundleMessageSource" in Spring Configuration File — ds-servlet.xml

Example12
JCode Cell
1 
2<?xml version="1.0" encoding="UTF-8"?>
3<beans xmlns="http://www.springframework.org/schema/beans"
4xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5xmlns:p="http://www.springframework.org/schema/p"
6xmlns:context="http://www.springframework.org/schema/context"
7xsi:schemaLocation="
8 http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans.xsd
10 http://www.springframework.org/schema/context
11http://www.springframework.org/schema/context/spring-context.xsd">
12 
13<context:component-scan base-package = "com.durgasoft.controller" />
14 
15<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
16<property name="basename" value="/com/durgasoft/resources/messages" />
17</bean>
18 
19<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
20<property name="defaultLocale" value="en" />
21</bean>
22 
23<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
24<property name="paramName" value="lang" />
25</bean>
26 
27<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
28<property name="interceptors">
29 <list>
30 <ref bean="localeChangeInterceptor" />
31 </list>
32</property>
33</bean>
34 
35<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
36<property name = "prefix" value = "/WEB-INF/" />
37<property name = "suffix" value = ".jsp" />
38</bean>
39 
40</beans>
41

"ResourceBundleMessageSource" in Spring Configuration File — web.xml

Example13
JCode Cell
1 
2<?xml version="1.0" encoding="UTF-8"?>
3<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
4<display-name>i18napp</display-name>
5<welcome-file-list>
6<welcome-file>index.html</welcome-file>
7<welcome-file>index.htm</welcome-file>
8<welcome-file>index.jsp</welcome-file>
9<welcome-file>default.html</welcome-file>
10<welcome-file>default.htm</welcome-file>
11<welcome-file>default.jsp</welcome-file>
12</welcome-file-list>
13<servlet>
14<servlet-name>ds</servlet-name>
15<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
16<load-on-startup>1</load-on-startup>
17</servlet>
18 
19<servlet-mapping>
20<servlet-name>ds</servlet-name>
21<url-pattern>/</url-pattern>
22</servlet-mapping>
23</web-app>
24
📝 Key Takeaways
  • The locale resolver decides the language; the interceptor is what lets the user change it
  • ResourceBundleMessageSource keys the same message across one file per locale
  • Once text lives in properties files, adding a language is a new file, not a code change