In an interview if difference between BeanFactory and ApplicationContext is asked one of the reason given by people to use ApplicationContext is the support for internationalization provided by ApplicationContext. This post shows the same thing; how Internationalization (i18n) using ApplicationContext and MessageSource can be provided in Spring.
Spring ApplicationContext and MessageSource
The ApplicationContext interface extends an interface called MessageSource in Spring framework which provides support for internationalization (i18n) functionality. Spring also provides the interface HierarchicalMessageSource, which can resolve messages hierarchically. Using these two interfaces Spring effects message resolution. The methods defined on these interfaces include:
- String getMessage(String code, Object[] args, String default, Locale loc)- The basic method used to retrieve a message from the MessageSource. When no message is found for the specified locale, the default message is used. In the properties file it will look for the key which is having the same values as code parameter.
- String getMessage(String code, Object[] args, Locale loc)- Essentially the same as the previous method, but with one difference: no default message can be specified; if the message cannot be found, a NoSuchMessageException is thrown.
- String getMessage(MessageSourceResolvable resolvable, Locale locale)- All properties used in the preceding methods are also wrapped in a class named MessageSourceResolvable, which you can use with this method.
When an ApplicationContext is loaded, it automatically searches for a MessageSource bean defined in the context. The bean must have the name messageSource. If such a bean is found, all calls to the preceding methods are delegated to the message source.
There are two MessageSource implementations provided by Spring framework ResourceBundleMessageSource and StaticMessageSource. The StaticMessageSource is rarely used but provides programmatic ways to add messages to the source. ResourceBundleMessageSource can be configured as shown below.
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
Internationalization example in Spring using MessageSource
Here we’ll have two properties file format and error, for locale specific files you add the locale along with the file name. If you are having format file for locale UK (en_gb) and US (en_us) then you will create two files format_en_GB.properties and format_en_US.properties.
While defining the message source bean you just need to provide the base name (i.e. format or error) based on the passed locale correct properties file will be picked.
Configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>config/format</value> <value>config/error</value> </list> </property> </bean> </beans>
Since the properties folder are inside config folder thus the name config/format and config/error.
format_en_GB.properties
dateformat=use date format dd/mm/yyyy
format_en_US.properties
dateformat=use date format mm/dd/yyyy
error_en_US.properties
argument.required=The {0} is required.
error_de.properties
argument.required=Der {0} ist erforderlich.
You can run it using the following code.
public class App { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext ("appcontext.xml"); System.out.println("date format msg " + context.getMessage( "dateformat", null, Locale.UK)); System.out.println("date format msg " + context.getMessage(" dateformat", null, Locale.US)); System.out.println("Name error msg " + context.getMessage("argument.required", new Object[]{"Name"}, Locale.US)); System.out.println("Name error msg " + context.getMessage("argument.required", new Object[]{"Name"}, Locale.GERMANY)); context.close(); } }
Output
date format msg use date format dd/mm/yyyy date format msg use date format mm/dd/yyyy Name error msg The Name is required. Name error msg Der Name ist erforderlich.
Accessing MessageSource in Spring Bean Using MessageSourceAware interface
In the above example the message is resolved using the ApplicationContext but in most of the scenarios you would need to resolve a message with in a bean. For that bean should implement the MessageSourceAware interface and use its setMessageSource() method to set the defined MessageSource.
Spring Example using MessageSourceAware
public class TestService implements MessageSourceAware { private MessageSource messageSource; @Override public void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } public void displayMessage(){ System.out.println("Name error msg " + messageSource.getMessage(" argument.required", new Object[]{"Name"}, Locale.US)); System.out.println("Name error msg " + messageSource.getMessage(" argument.required", new Object[]{"Name"}, Locale.GERMANY)); } }
The configuration you need to add for this bean is as follows.
<bean id="testService" class="org.netjs.config.TestService"> <property name="messageSource" ref="messageSource" /> </bean>
You can run it using the following code.
public class App { public static void main(String[] args) { AbstractApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml"); TestService testService = context.getBean("testService", TestService.class); testService.displayMessage(); context.close(); } }
Which gives following output-
Name error msg The Name is required. Name error msg Der Name ist erforderlich.
That's all for this topic Spring MessageSource Internationalization (i18n) Support. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Spring Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment