≡ Menu
Spring Tutorial: i18n

Spring Tutorial: Learn about i18n

Spring Tutorial: Internationalization

This Spring Tutorial, looks at Internationalization (i18n)

Also, how to pass parameters to i18n’ed messages.

 

If this Spring Tutorial helps you and you would like the full source code and even better a free online video on this topic, so you actually watch the steps taken and follow along click here!

Remember Sharing is caring! So if you get something from this Spring tutorial please share it with others on facebookgoogle+, LinkedIn, Twitter  etc… so it may help them too! :)

If you want to make your Java application truly international and not have to worry about all the framework type code needed to make it happen. You would be hard pressed to find anything better than the Spring Framework.

In this Spring Tutorial, I want to take a quick look at how internationalization or i18n for short can be achieved easily using the Spring Framework. The principles shown here are good for stand alone Java applications and Web applications.

As an example, I want an internationalized (i18n) versions of an early morning wake up call ! Also to make it more personalized I would like to include some names; i.e. the name of the person being woken up and the name of the person doing the waking-up!

So in summary, I want to parameterize the peoples names in the wake-up call message and to make the message ‘internationalized‘ i18n’ed, so I can have English and French versions of the wake-up call.

There will be a specific text message for each day of the week and the British, English version of the text message will look like;

“Rise and shine Fred, this is your Sunday morning message! from Bill.”

In this case the names to be parameterized are Fred and Bill

We want the ability to injected different names if needed, so they’re not hardwired into the text message itself.

We can do this with a placeholder, denoted by curly braces {} with a numeric index inside.

e.g.  {0} for the first parameter placeholder and {1} for the second placeholder and so on depending on how many parameters you have.

The message above would now look like;

“Rise and shine {0}, this is your Sunday morning message! from {1)”

All our text messages are held within a properties file(s) and each text message would also need a unique key to identify it.

Here, as I will have a unique text message for each day of the week, I plan to use the index of the day of the week to uniquely Identify a related text message.

As an example, 1 denotes a day of the week,  1 = Sunday.  In fact the key itself will look like;

messageoftheday.1
(The “1” is prefixed with messageoftheday which acts as a kind of namespace to ensure its unique in the file and also to helps describe the property value.)

The completed entry in the property file will look like this: <key>=<value>

messageoftheday.1=Rise and shine {0} this is your Sunday morning message! from {1}

The contents of the property file would look like, (for each day of the week);
messageoftheday.1=Rise and shine {0} this is your Sunday morning message! from {1}
messageoftheday.2=Rise and shine {0} is your Monday morning message! from {1}
messageoftheday.3=Rise and shine {0} is your Tuesday morning message! from {1}
messageoftheday.4=Rise and shine {0} is your Wednesday morning message! from {1}
messageoftheday.5=Rise and shine {0} is your Thursday morning message! from {1}
messageoftheday.6=Rise and shine {0} is your Friday morning message! from {1}
messageoftheday.7=Rise and shine {0} is your Saturday morning message! from {1}

 

Property File:

It goes to say that you will need a separate properties file for each Locale you plan to support. i.e. A Locale covers not just a country but a specific language within a country. French language in France maybe different to the French language in Canada or Switzerland. The Locale helps to solve this.

The property file containing the above text messages needs a file name to express the locale using the language and country code.

So, for British English this file would be named something like;

messages_en_GB.properties

Also, these property file needs to live in your resources folder on the classpath,  otherwise Spring will not find them !

As another example;

The French version in the French language would be;

messages_fr_FR.properties

(Note the root file name ‘messages’ is the same.)

This properties file contains the French language version;

messageoftheday.1= {0}, Ceci est votre message de Dimanche matin! à partir de {1}
messageoftheday.2= {0}, Ceci est votre message de Lundi matin! à partir de {1}
messageoftheday.3= {0}, C’est votre message Mardi matin! à partir de {1}
messageoftheday.4= {0}, Ceci est votre message Mercredi matin! à partir de {1}
messageoftheday.5= {0}, Ceci est votre message de Jeudi matin! à partir de {1}
messageoftheday.6= {0}, Ceci est votre message de Vendredi matin! à partir de {1}
messageoftheday.7= {0}, C’est votre message Samedi matin! à partir de {1}

 

Now we have the properties files created for each Locale, how do we access the contents using the Spring Framework  ?

Step: 1
Do some Spring bean configuration in Spring XML or Spring JavaConfig:

In Spring XML …
We need to define the MessageSource bean definition;

(Note: if you’re running a web application, take a look at;
org.springframework.context.support.ReloadableResourceBundleMessageSource )

OR in Spring JavaConfig the same definition looks like;

@Bean
public MessageSource messageSource(){
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames(“i18n/messages”);
return messageSource;
}

(Note: Remember to set the basename or basenames, the relative path to where your message property files are located.)

Step: 2
Inject the messageSource into your service class for access:
@Inject()
private MessageSource messageSource;

Step:3
Access the injected messageSource to retrieve Locale specific messages, we also need to consider how to pass the parameters required, remember the {0} and {1}
Here I implement a “String getMessage()” method to return the String message with parameters injected.

public String getMessage() {

// What day is it today, so we can look up the message??
final int day = GregorianCalendar.getInstance().get(Calendar.DAY_OF_WEEK);

// create a new Locale instance based on the language and country codes
// France / French is used for this example.
final Locale locale = new Locale(“fr”, “FR”);

// create a String array containing the names we want injected into the
// message.
final String[] args = {“Fred”, “Bill”};

//Access the locale specific message, using a key, the String array and Locale for France.
final String result = messageSource.getMessage(KEY_PREFIX + day, args , locale);

//Result is the French message with the names injected.
return result;
}

The result of the above is;
“Fred, Ceci est votre message de Vendredi matin! à partir de Bill”

The names (Fred and Bill) and the country and language codes are now hard coded into out Java application code, well it’s easy to externalize them into a different properties file and have those values also injected by Spring. I will cover that in my next Spring tutorial on ‘Externalizing data in Spring’.

Learn all about Core Spring with these online Spring Tutorials

Remember Sharing is caring!  If you enjoyed this Spring tutorial, help others by sharing it on facebook, google+ LinedIn or twitter and remember full source code is available and a free online video of this Spring tutorial, so you actually watch the steps taken and follow along click here!

Happy Coding!

Bruce

in Blog from the Den, Spring Tutorials

About the author: Bruce is a techie, a gadget geek, programmer, mentor and all round technology nut. He holds two degrees in computer science, with over 25 years in the software business. Currently working freelance as a software engineer and programming mentor. He loves what technology can do for us. Building applications using functional, Object Orientated languages & polyglot persistence helps him reconnect with the feeling of building something tangible. To learn more about Bruce, follow him on Twitter @denofprogram

{ 0 comments… add one }

Leave a Comment