打开testspring工程
新建包:com.testspring.message 放置存放各种消息的propertise文件。
新建包:com.testspring.services 放置获取propertise文件的服务类。
结构如下:
message包下新建:
message_en_US.properties文件。加入以下内容:
say = hello !
没错就是这一句。
新建文件:
message_zh_CN.txt 文件(注意以UTF-8模式保存),加入 say = 你好!。接着cmd进入命令行模式,cd到message_zh_CN.txt目录下,敲入命令:
native2ascii -encoding UTF-8 message_zh_CN.txt message_zh_CN.properties
随即在message_zh_CN.txt所处目录下会生成message_zh_CN.properties文件,用记事本打开,会发现里面是一行有规则的乱码:
say = /u4f60/u597d/uff01
因为限于java的ResourceBundle的限制,java读取字符的格式仅限于基本的ASCII字符和经过Unicode编码后的字符,而中文字符,就必须要通过sun公司jdk中提供的native2ascii 命令将中文Unicode编码为UTF-8通用字符,以供程序读取。
这里在转换时,如发现命令行提示native2ascii不是内部或外部命令(大意),应该是jdk中的bin目录没有加入到系统变量中。
而 message_xxx.properties 分别有两个message_en_US.properties 、message_zh_CN.properties ,java提供对I18N规范的支持,它通过N个不同文件名的属性文件给应用程序提供不同语言区域的显示信息,文件名是按照国际化组织严格规定的,如message_xxx.properties ,message 用户自定随便什么都可以,而xxx就必须遵循规定来命名,英语(美国)为en_US,中文(中国大陆)为zh_CN,中文(台湾)为zh_TW 等等诸如此类。
资源文件完成以后,在services包下新建类:TestI18N.java,因为在这个类读取资源文件需要获取Spring容器的引用,因此必须实现ApplicationContextAware接口。
- package com.testspring.services;
- import java.util.Locale;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- public class TestI18N implements ApplicationContextAware {
- private ApplicationContext context;
- private Locale locale = Locale.getDefault();
- public void setApplicationContext(ApplicationContext context)
- throws BeansException {
- this.context = context;
- }
- public String sayHello(){
- return context.getMessage("say", null,"没有字段!",locale);
- }
- public void setContext(ApplicationContext context) {
- this.context = context;
- }
- public void setLocale(Locale locale) {
- this.locale = locale;
- }
- }
代码中的sayHello负责通过获取资源文件的say字段对外提供说出hello,只有一句话:
return context.getMessage("say", null,"没有字段!",locale);
返回从spring容器读取到的message_xxx.properties 的say字段的信息。getMessage(资源文件字段名, 文字中的可变内容 , 没有找到资源文件后的默认内容 , 当前操作系统的语言区域信息。
资源文件和国际化类都准备好了,但怎么才能让Spring在初始化时就把资源文件加载呢?跟Struts国际化一样,都是从xml配置文件写入相关配置即可。而Spring是通过配置一个管理bean,然后注入属性来实现的。
打开spring的bean配置文件:applicationContext.xml ,在bean声明中加入:
- ..........
- <!-- 国际化bean -->
- <bean id="messageSource"
- class="org.springframework.context.support.ReloadableResourceBundleMessageSource" >
- <property name="basename" value="com/testspring/message/message"></property>
- </bean>
- <!-- 国际化测试类 -->
- <bean id="testi18n" class="com.testspring.services.TestI18N" >
- </bean>
- ..........
国际化bean:这个类是Spring提供的继承了java.util.ResourceBundle 类,因此用它可以解析国际化信息。bean的id是规定好的,一定要用" messageSource " 。它的属性" basename ",指出了资源文件的位置(位置是基于src下的相对路径)。
Spring初始化bean时会实例化这个类,从而从注入的basename属性提供的值读取message_xxx.properties资源文件,而测试类中getMessage(...)方法传入的locale中的语言区域信息则决定了Spring将读取哪个资源文件。
也可以将语言区域硬编码,如:
- <bean id="testi18n" class="com.testspring.services.TestI18N" >
- <property name="locale" value="en_US"></property>
- </bean>
这样即使在getMessage(..)中传入操作系统的区域语言信息,也不会起任何作用,Spring将读取en_US资源文件的字段反馈。
最后,在main包下新建类:TestI18NMain.java类测试程序。
- package com.testspring.main;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import com.testspring.services.TestI18N;
- public class TestI18NMain {
- public static void main(String[] arg0){
- ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
- String str = ((TestI18N)context.getBean("testi18n")).sayHello();
- System.out.println("嘿!" + str);
- }
- }
将 TestI18NMain 作为javaApplication 程序运行,如果操作系统语言区域是中文(大陆)的话,运行得出:
org.springframework.context.support.ClassPathXmlApplicationContext@c1b531: display name [org.springframework.context.support.ClassPathXmlApplicationContext@c1b531]; startup date [Sun Sep 07 17:20:13 GMT+07:00 2008]; root of context hierarchy
嘿!你好!