随着互联网的发展,越来越多的企业和个人开始关注全球化的需求。在这个背景下,多语言支持成为了一个重要的课题。Spring框架作为一款优秀的Java开发框架,提供了丰富的i18N支持,能帮助搬砖工快速实现多语言应用。
1、i18n概述
国际化也称作 i18n ,其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数。由于软件发行可能面向多个国家,对于不同国家的用户,软件显示不同语言的过程就是国际化。通常来讲,软件中的国际化是通过配置文件来实现的,假设要支撑两种语言,那么就需要两个版本的配置文件。
2、Java国际化
(1)Java自身是支持国际化的,java.util.Locale
用于指定当前用户所属的语言环境等信息,java.util.ResourceBundle
用于查找绑定对应的资源文件。Locale包含了language
信息和country
信息,Locale创建默认locale对象时使用的静态方法:
/** * 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)配置文件命名规则
Spring i18N的核心是资源文件,这些文件通常以.properties
或.yml
格式存储,用于存储应用程序中需要翻译的文本信息。资源文件中的键值对表示了一种特定的翻译关系。例如:
test=Hello, world!
文件命名必须遵循basename_language_country.properties
规则,java才会识别。其中,basename是必须的,语言和国家是可选的。这里存在一个优先级概念,如果同时提供了messages.properties
和messages_zh_CN.propertes
两个配置文件,如果提供的locale符合en_CN
,那么优先查找messages_en_CN.propertes
配置文件,如果没查找到,再查找messages.properties
配置文件。最后,提示下,所有的配置文件必须放在classpath
中,一般放在resources目录下
(3)实验:演示Java国际化
第一步
创建模块spring6-i18n,引入spring依赖
第二步
在resource目录下创建两个配置文件:messages_zh_CN.propertes
和 messages_en_GB.propertes
第三步
测试:
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国际化
3.1、MessageSource接口
spring中国际化是通过MessageSource
这个接口来支持的
常见实现类
ResourceBundleMessageSource
:
这个是基于Java的ResourceBundle基础类实现,允许仅通过资源名加载国际化资源。它可以将指定的资源文件中的键值对映射为消息。
例如:
- 创建一个名为messages.properties的资源文件,并在其中添加一些键值对
greeting=Hello, world!
- 在Spring配置文件中配置ResourceBundleMessageSource
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:messages</value> </list> </property> </bean>
- 在代码中使用ResourceBundleMessageSource获取消息
@Autowired private ResourceBundleMessageSource messageSource; public void sayHello() { String greeting = messageSource.getMessage("greeting", null, LocaleContextHolder.getLocale()); System.out.println(greeting); // 输出 "Hello, world!" }
首先通过@Autowired
注解将ResourceBundleMessageSource
注入到当前类中。然后,在sayHello方法中,调用messageSource.getMessage
方法来获取“greeting”键对应的值。该方法的第一个参数是要查找的键名,第二个参数是可选的参数列表,第三个参数是Locale对象,表示要查找的语言环境。如果不指定Locale对象,则默认使用当前系统的Locale。
ReloadableResourceBundleMessageSource
:
这个功能和第一个类的功能类似,多了定时刷新功能,允许在不重启系统的情况下,更新资源的信息
StaticMessageSource
:
它允许通过编程的方式提供国际化信息,一会我们可以通过这个来实现db中存储国际化信息的功能。
3.2、使用Spring6国际化
第一步 创建资源文件
国际化文件命名格式:基本名称 _ 语言 _ 国家.properties
{0},{1}这样内容,就是动态参数
(1)创建example_en_US.properties
www.example.com=welcome {0},时间:{1}
(2)创建example_zh_CN.properties
www.example.com=欢迎 {0},时间:{1}
第二步 创建spring配置文件,配置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>
第三步 创建测试类
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); } }