When building a software or a web site meant for world wide users, the first thing you would like to do is make your site run in a variety of languages like French, Spanish, English, Hindi et all.

When building a site which will support different languages, the most important thing to keep in mind is NEVER HARDCODE STRING LABELS IN YOUR CODE. Best way is to separate the static strings into a properties file often called as messages.properties file. Then we load this using java's ResourceBundle functionality. Now lets us look at the Spring's way of doing this.

Create a properties file containing your static strings or messages in your default language i.e English.

messages.properties

name.question = What is your name? 
welcome.message = Welcome guest
					

Next thing we will do is to add translated values of these keys in a separate file. NOTE ! The conventions for naming such a file is that you need to append the name of the file with an "underscore" sign followed by the locale code of the language you are translating the file to. So if you are creating a french version of the above file then its name would be messages_fr.properties and the message keys will now contain the french strings like:

messages_fr.properties

name.question = Quel est votre nom? 
welcome.message = Bienvenue cher invité!
					

Now lets tell the spring to handle the localization by using the above files. This is done by creating a bean of type ResourceBundleMessageSource in the following way. The attribute to be noted here is the basename. This tells the Spring where to look for the properties file when a request for localized text comes in.(We will see that in a moment). In line no 8 below, we tell the Spring framework to look for file named messages.properties file in the classpath. It is called as basename because, whenever the request for a localized string comes, the locale or language code will be automatically appended to the basename value. So if the french string is requested, then messages_fr will be automatically picked from the classpath.

messageContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
		<property name="basename" value="messages"></property>
	</bean>

</beans>

Spring provides an Inteface which is used to load messages. This interface is called org.springframework.context.MessageSource. And the object that implements is the ClassPathXmlApplicationContext, that we have already seen in the previous tutorials. So all we have to do is just initialize the ApplicationContext object.

ApplicationContext context = new ClassPathXmlApplicationContext(
				"i18n/messageContext.xml");
String englishMsg = context.getMessage("name.question",null, Locale.ENGLISH);
String frenchMsg = context.getMessage("name.question",null, Locale.FRENCH);
System.out.println(englishMsg + " "+ frenchMsg );

Working with placeholder messages

Going a little deeper, you may also require to create string with some placeholder text that you wana provide later or based on some condition in your code. For example : you want to load a welcome message specific to a user. So, lets create new property with the placeholder text represented by {0} {1} {2} ... in the following way:

welcome.user = Welcome {0}

Our previous code will be slightly modified to pass in an array of strings which will take the place of the placeholders in the message key. In the following code, we are passing in a string "Apurav Chauhan" which will replace {0} in the welcome.user key in the above message file.

String customMsg = context.getMessage("welcome.user",new Object[]{"Apurav Chauhan"}, Locale.ENGLISH);

Simple! Isn't it? ;)

Download Source