<beans>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
</beans>
i18n using MessageSource
The ApplicationContext interface extends an interface called MessageSource, and
therefore provides internationalization (i18n) functionality. Spring also provides the
interface HierarchicalMessageSource, which can resolve messages hierarchically.
Together these interfaces provide the foundation upon which 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 theMessageSource. When no message is found for the specified locale, the default message is used. Any arguments passed in become replacement values, using theMessageFormatfunctionality provided by the standard library. -
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, aNoSuchMessageExceptionis thrown. -
String getMessage(MessageSourceResolvable resolvable, Locale locale): All properties used in the preceding methods are also wrapped in a class namedMessageSourceResolvable, 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. If no
message source is found, the ApplicationContext attempts to find a parent containing a
bean with the same name. If it does, it uses that bean as the MessageSource. If the
ApplicationContext cannot find any source for messages, an empty
DelegatingMessageSource is instantiated in order to be able to accept calls to the
methods defined above.
Spring provides two MessageSource implementations, ResourceBundleMessageSource and
StaticMessageSource. Both implement HierarchicalMessageSource in order to do nested
messaging. The StaticMessageSource is rarely used but provides programmatic ways to
add messages to the source. The ResourceBundleMessageSource is shown in the following
example:
In the example it is assumed you have three resource bundles defined in your classpath
called format, exceptions and windows. Any request to resolve a message will be
handled in the JDK standard way of resolving messages through ResourceBundles. For the
purposes of the example, assume the contents of two of the above resource bundle files
are…
# in format.properties
message=Alligators rock!
# in exceptions.properties
argument.required=The {0} argument is required.
A program to execute the MessageSource functionality is shown in the next example.
Remember that all ApplicationContext implementations are also MessageSource
implementations and so can be cast to the MessageSource interface.
public static void main(String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("message", null, "Default", null);
System.out.println(message);
}
The resulting output from the above program will be…
Alligators rock!
So to summarize, the MessageSource is defined in a file called beans.xml, which
exists at the root of your classpath. The messageSource bean definition refers to a
number of resource bundles through its basenames property. The three files that are
passed in the list to the basenames property exist as files at the root of your
classpath and are called format.properties, exceptions.properties, and
windows.properties respectively.
The next example shows arguments passed to the message lookup; these arguments will be converted into Strings and inserted into placeholders in the lookup message.
<beans>
<!-- this MessageSource is being used in a web application -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="exceptions"/>
</bean>
<!-- lets inject the above MessageSource into this POJO -->
<bean id="example" class="com.foo.Example">
<property name="messages" ref="messageSource"/>
</bean>
</beans>
public class Example {
private MessageSource messages;
public void setMessages(MessageSource messages) {
this.messages = messages;
}
public void execute() {
String message = this.messages.getMessage("argument.required",
new Object [] {"userDao"}, "Required", null);
System.out.println(message);
}
}
The resulting output from the invocation of the execute() method will be…
The userDao argument is required.
With regard to internationalization (i18n), Spring’s various MessageSource
implementations follow the same locale resolution and fallback rules as the standard JDK
ResourceBundle. In short, and continuing with the example messageSource defined
previously, if you want to resolve messages against the British (en-GB) locale, you
would create files called format_en_GB.properties, exceptions_en_GB.properties, and
windows_en_GB.properties respectively.
Typically, locale resolution is managed by the surrounding environment of the application. In this example, the locale against which (British) messages will be resolved is specified manually.
# in exceptions_en_GB.properties
argument.required=Ebagum lad, the {0} argument is required, I say, required.
public static void main(final String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("argument.required",
new Object [] {"userDao"}, "Required", Locale.UK);
System.out.println(message);
}
The resulting output from the running of the above program will be…
Ebagum lad, the 'userDao' argument is required, I say, required.
You can also use the MessageSourceAware interface to acquire a reference to any
MessageSource that has been defined. Any bean that is defined in an
ApplicationContext that implements the MessageSourceAware interface is injected with
the application context’s MessageSource when the bean is created and configured.
|
Note
|
As an alternative to |