国际化信息
程序员文章站
2022-03-03 12:33:00
...
国际化信息
文章目录
一、基础知识
一般需要**”语言类型“和”国家/地区类型“**,才可以确定一个特定类型的本地化信息。
1.1 Locale
1.2 本地化工具类
-
NumberFormat
可以对货币金额进行格式化操作 -
DateFormat
可以对日期进行格式化操作 -
MessageFormat
在NumberFormat
和DateFormat
对基础上提供了强大的占位符字符串的格式化功能
1.3 ResourceBundle
加载本地化资源
国际化资源文件的命名规范:<资源名>_<语言代码>_<国家/地区代码>.properties
不同的资源文件,虽然属性值不同,但属性名却是相同的。
.
└── i18n
├── resource_en_US.properties
└── resource_zh_CN.properties
private static void resourceBoundle(){
ResourceBundle rb1 = ResourceBundle.getBundle("i18n/resource", Locale.US);
ResourceBundle rb2 = ResourceBundle.getBundle("i18n/resource", Locale.CHINA);
System.out.println("us: " + rb1.getString("greeting.afternoon"));
System.out.println("cn: " + rb2.getString("greeting.afternoon"));
}
1.4 在资源文件中使用格式化串:ResourceBoundle+MessageFormat
String pattern1 = "{0}, 您好,{1} {2}";
Object[] params = {"John", new GregorianCalendar().getTime(), 1.0E3};
String format0 = MessageFormat.format(pattern1, params);
String format1 = new MessageFormat(rb1.getString("greeting.welcome"),Locale.US).format(params);
String format2 = new MessageFormat(rb2.getString("greeting.welcome"),Locale.CHINA).format(params);
二、Spring对国际化的支持
2.1 MessageSource
2.2 ResourceBundleMessageSource
<bean id="myResource" class="org.springframework.context.support.ResourceBundleMessageSource">
<!-- 通过基名指定资源,相对于类跟路径-->
<property name="basenames">
<list>
<value>i18n/resource</value>
</list>
</property>
</bean>
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MessageSource myResource = context.getBean("myResource", MessageSource.class);
Object[] params = {"John", new GregorianCalendar().getTime(), 1.0E3};
String format1 = myResource.getMessage("greeting.welcome", params, Locale.US);
String format2 = myResource.getMessage("greeting.welcome", params, Locale.CHINA);
System.out.println(format1);
System.out.println(format2);
2.3 ReloadableResourceBundleMessageSource
和ResourceBundleMessageSource
唯一的区别是可以定时刷新资源文件,以便在应用程序不重启的情况下感知资源文件的变化。
<bean id="myReloadResource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 通过基名指定资源,相对于类跟路径-->
<property name="basenames">
<list>
<value>i18n/resource</value>
</list>
</property>
<!-- 设置cacheSeconds 属性让 ReloadableResourceBundleMessageSource 每隔5秒刷新一次资源文件。
在真实的情况下,太过频繁的刷新将会带来性能上的负面影响,一般不建议小于1分钟。 -->
<!-- cacheSeconds 默认值为 -1, 表示永不刷新, 此时退化为 ResourceBundleMessageSource 功能 -->
<property name="cacheSeconds" value="5"/>
</bean>
提示:在测试的时候,一定要确认修改后的i18n
文件保存成功了
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MessageSource myReloadResource = context.getBean("myReloadResource", MessageSource.class);
Object[] params = {"John", new GregorianCalendar().getTime(), 1.0E3};
try {
for (int i = 0; i < 10; i++) {
String format1 = myReloadResource.getMessage("greeting.welcome", params, Locale.US);
String format2 = myReloadResource.getMessage("greeting.welcome", params, Locale.CHINA);
System.out.println(format1);
System.out.println(format2);
// 模拟程序应用, 在次期间,更改资源文件
System.out.println("间隔十秒...");
Thread.currentThread().sleep(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
2.4 容器级的国际化信息资源
在MessageSource
的类结构中,发现ApplicationContext
实现了MessageSoruce
的接口。也就是说,ApplicationContext
的实现类本身也是一个MessageSource
对象。
声明容器级别的国际化信息资源:
注册资源Bean,其Bean名称只能为messageSource
<!-- 声明容器级的国际化信息资源, 注册的这个Bean, 其Bean名称只能为 messageSource -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>i18n/resource</value>
</list>
</property>
</bean>
如果没有声明messageSource
,通过 下面的代码将会抛出异常:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Object[] params = {"John", new GregorianCalendar().getTime(), 1.0E3};
String format1 = context.getMessage("greeting.welcome", params, Locale.US);
String format2 = context.getMessage("greeting.welcome", params, Locale.CHINA);
System.out.println(format1);
System.out.println(format2);