The MessageSource interface supports the parameterization and internationalization of messages and provides 2 implementations:
- ResourceBundleMessageSource, built on top of the standard ResourceBundle
- ReloadableResourceBundleMessageSource, being able to reload message definitions without restarting the VM
The following is an example of ResourceBundleMessageSource to get messages in the specified language in Spring 3.
- create a java project in your preferred IDE (eclipse, netbeans, etc.)
- configure the project with Maven with file pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Autowired</groupId> <artifactId>Autowired</artifactId> <version>0.0.1-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source /> <target /> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.1.2.RELEASE</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> </project>
otherwise you can use the following library:
- spring-context-3.1.2.RELEASE.jar
- spring-aop-3.1.2.RELEASE.jar
- aopalliance-1.0.jar
- spring-beans-3.1.2.RELEASE.jar
- spring-core-3.1.2.RELEASE.jar
- commons-logging-1.1.1.jar
- spring-expression-3.1.2.RELEASE.jar
- spring-asm-3.1.2.RELEASE.jar
- log4j-1.2.17.jar
- create a folder “resources” and add to the classpath
- create the file resources/app-context.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" default-lazy-init="true"> <context:component-scan base-package="eu.lucazanini" /> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames"> <list> <value>messages</value> </list> </property> </bean> </beans>
as explained below, the string “messages” is equal to the first part of the name of the files .properties, and you can specify a path from the classpath such as “locale/messages” for example
- create the file resources/log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p %c{1}:%L %m %n" /> <!-- ConversionPattern format specification %d inserts the date; you can specify the format (%d{yyyy-MM-dd HH:mm:ss,SSS}) %-5p inserts the priority log level, 5 characters, left justified %c{1} inserts the name of the class %L inserts the line number %m inserts the user message %n inserts the separator (for example, a new line) --> </layout> </appender> <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender"> <param name="append" value="false" /> <param name="Threshold" value="DEBUG" /> <param name="File" value="logs/app.log"/> <param name="MaxFileSize" value="512KB" /> <param name="MaxBackupIndex" value="10" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p %c{1}:%L %m %n" /> </layout> </appender> <!--sets the priority log level for org.springframework--> <logger name="org.springframework"> <level value="info"/> </logger> <!--sets the priority log level for eu.lucazanini--> <logger name= "eu.lucazanini"> <level value="debug"/> </logger> <!--sets the default priority log level--> <root> <priority value="debug"></priority> <appender-ref ref="stdout"/> <appender-ref ref="fileAppender"/> </root> </log4j:configuration>
- create the 3 file .properties to manage the content of messages in english language (Great Britain), english language (United States) and italian language
- resources/messages_en_GB.properties
msg1=in british english msg2=My name is {0} {1}
- resources/messages_en_US.properties
msg1=in american english msg2=My name is {0} {1}
- resources/messages_it.properties
msg1=in italiano msg2=Il mio nome è {0} {1}
the names of the files .properties are important and must comply with one of the following syntaxes:
- [base name]_[language]
- [base name]_[language]_[country]
- [base name]_[language]_[country]_[variant]
where
- [base name] is that specified in resources/app-context.xml (“messages” in this example)
- [language] is the language code (“en”, “it”, etc.)
- [country] is the country code (“GB”,”US”, “IT”, the same language changes depending on the country, the english spoken in the United States is different from that spoken in England)
- [variant] is a code for the variant of the language (not used in this example)
- resources/messages_en_GB.properties
- create the eu/lucazanini/messagesource/Main.java
package eu.lucazanini.messagesource; import java.util.Locale; import org.apache.log4j.Logger; import org.springframework.context.support.GenericXmlApplicationContext; public class Main { private static Logger log = Logger.getLogger(Main.class); public static void main(String[] args) { GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(); ctx.load("classpath:app-context.xml"); ctx.refresh(); Locale britishEnglish = new Locale("en", "GB"); System.out.println(ctx.getMessage("msg1", null, britishEnglish)); System.out.println(ctx.getMessage("msg2", new Object[] { "Luca", "Zanini" }, britishEnglish)); System.out.println("\n"); Locale americanEnglish = new Locale("en", "US"); System.out.println(ctx.getMessage("msg1", null, americanEnglish)); System.out.println(ctx.getMessage("msg2", new Object[] { "Luca", "Zanini" }, americanEnglish)); System.out.println("\n"); Locale italian = new Locale("it"); System.out.println(ctx.getMessage("msg1", null, italian)); System.out.println(ctx.getMessage("msg2", new Object[] { "Luca", "Zanini" }, italian)); } }
I use the method String getMessage(String code, Object[] args, Locale locale) where
- code to look up in the files .properties
- args is an object array to pass as arguments and they replace {0} {1} {2} … in the files .properties, use “null” if you don’t have arguments
- Locale is an object of Locale class and has 3 constructors:
- Locale(String language)
- Locale(String language, String country)
- Locale(String language, String country, String variant)
you can also use the method String getMessage(String code, Object[] args, String defaultMessage, Locale locale) where you can specify a default value for the message
- launch the application
in british english My name is Luca Zanini in american english My name is Luca Zanini in italiano Il mio nome è Luca Zanini
References:
MessageSource
Locale
Leave a Reply