With the development of the Internet, more and more enterprises and individuals have begun to pay attention to the needs of globalization. In this context, multilingual support becomes an important topic. As an excellent Java development framework, the Spring framework provides rich i18N support, which can help bricklayers quickly implement multilingual applications.
1. Overview of i18n
Internationalization is also called i18n . Its source is the first and last characters i and n of the English word internationalization, and 18 is the number of characters in the middle. Since software releases may target multiple countries, the process of software displaying different languages for users in different countries is internationalization. Generally speaking, internationalization in software is achieved through configuration files. If two languages are to be supported, then two versions of configuration files are required.
2. Java internationalization
(1) Java itself supports internationalization, java.util.Locale
which is used to specify information such as the locale to which the current user belongs, and java.util.ResourceBundle
to find the resource file corresponding to the binding. Locale contains language
information and country
information, the static method used by Locale to create the default locale object:
/**
* This method must be called only for creating the Locale.*
* constants due to making shortcuts.
*/
private static Locale createConstant(String lang, String country) {
BaseLocale base = BaseLocale.createInstance(lang, country);
return getInstance(base, null);
}
(2) Configuration file naming rules
The core of Spring i18N is the resource file, which is usually stored in .properties
or .yml
format, and is used to store the text information that needs to be translated in the application. A key-value pair in a resource file represents a specific translation relationship. For example:
test=Hello, world!
File naming must follow basename_language_country.properties
the rules before java will recognize it. Among them, basename is required, language and country are optional. There is a priority concept here. If two configuration files are provided at the same time messages.properties
, messages_zh_CN.propertes
if the provided locale matches en_CN
, then the configuration file is searched first messages_en_CN.propertes
, and if not found, messages.properties
the configuration file is searched again. Finally, under the prompt, all configuration files must be placed classpath
in, generally placed in the resources directory
(3) Experiment: Demonstration of Java Internationalization
first step
Create the module spring6-i18n and introduce spring dependencies
second step
Create two configuration files under the resource directory: messages_zh_CN.propertes
andmessages_en_GB.propertes
third step
test:
package com.example.spring6.javai18n;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.ResourceBundle;
public class Demo1 {
public static void main(String[] args) {
System.out.println(ResourceBundle.getBundle("messages",
new Locale("en","GB")).getString("test"));
System.out.println(ResourceBundle.getBundle("messages",
new Locale("zh","CN")).getString("test"));
}
}
3. Spring6 internationalization
3.1, MessageSource interface
Internationalization in spring is MessageSource
supported through this interface
Common implementation classes
ResourceBundleMessageSource
:
This is an implementation based on the Java-based ResourceBundle base class, allowing internationalized resources to be loaded only by resource names. It can map key-value pairs in the specified resource file to messages.
For example:
- Create a resource file called messages.properties and add some key-value pairs to it
greeting=Hello, world!
- Configure ResourceBundleMessageSource in the Spring configuration file
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
</list>
</property>
</bean>
- Use ResourceBundleMessageSource in code to get messages
@Autowired
private ResourceBundleMessageSource messageSource;
public void sayHello() {
String greeting = messageSource.getMessage("greeting", null, LocaleContextHolder.getLocale());
System.out.println(greeting); // 输出 "Hello, world!"
}
First, inject it into the current class through @Autowired
annotations . ResourceBundleMessageSource
Then, in the sayHello method, call messageSource.getMessage
the method to get the value corresponding to the "greeting" key. The first parameter of this method is the key name to be found, the second parameter is an optional parameter list, and the third parameter is a Locale object, indicating the locale to be found. If the Locale object is not specified, the Locale of the current system will be used by default.
ReloadableResourceBundleMessageSource
:
This function is similar to the function of the first class, with the added timing refresh function, allowing resource information to be updated without restarting the system
StaticMessageSource
:
It allows to provide internationalization information through programming, and we can use this to realize the function of storing internationalization information in db.
3.2, using Spring6 internationalization
The first step is to create resource files
Internationalization file naming format: basename_language_country.properties
Contents like {0}, {1} are dynamic parameters
(1) Create example_en_US.properties
www.example.com=welcome {0},时间:{1}
(2) Create example_zh_CN.properties
www.example.com=欢迎 {0},时间:{1}
The second step is to create a spring configuration file and configure MessageSource
<?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.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>example</value>
</list>
</property>
<property name="defaultEncoding">
<value>utf-8</value>
</property>
</bean>
</beans>
The third step is to create a test class
package com.example.spring6.javai18n;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
import java.util.Locale;
public class Demo2 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//传递动态参数,使用数组形式对应{0} {1}顺序
Object[] objs = new Object[]{
"example",new Date().toString()};
//www.example.com为资源文件的key值,
//objs为资源文件value值所需要的参数,Local.CHINA为国际化为语言
String str=context.getMessage("www.example.com", objs, Locale.CHINA);
System.out.println(str);
}
}