Spring framework(7):国际化支持 i18n

来源:互联网 发布:全景视频拼接软件 编辑:程序博客网 时间:2024/05/29 08:08
Spring 国际化 i18n


以下完整示例代码地址:https://gitee.com/assad/springframework-test-i18n

关于 Java 本身对于 i18n 的支持,参见:http://blog.csdn.net/al_assad/article/details/78689808

MessageSource

Spring 定义了访问国际化信息的 MessageSouce (org.springframework.context.MessageSource) ,并提供了一系列易用的实现类;
该接口的定义了以下几个比较重更要的方法:
String getMessage(String code,Object[] args,String defaultMessage,Locale lcoale)code 表示国际化信息中国的属性名;
args用于传递格式化字符串的运行参数;
当资源找不到对应的属性名时,返回 defaultMessage参数指定的默认信息;
locale 表示本地化对象;String getMessage(String code,Object[] args,Locale lcoale)与以上方法类似,但当找不到对应的属性名时,直接抛出NoSuchMessageException 异常;String getMessage(MessageSourceResolvable resovable,Locale locale)MessageSoucreresolvable 将以上属性名、参数数组、默认信息封装起来

 MessageSource的体系结构

ResourceBundleMessageSource 是一个基本的实现类;
ReloadbleReourceBundleMessageSource 提供了定时刷新功能,可以在不重启系统的情况下更新资源的信息;
StaticMessageSource 主要用于程序测试,允许通过编码的形式提供国际化信息;

ResourceBundleMessageSource 

该实现类允许通过 beanName 指定一个资源名,或者通过 beanNames 指定一组资源名;
示例代码模块site.assad.springi18n/I18nTest.class;site.assad.i18n/resource;site.assad.springi18n/beans.xml
beans.xml 中的相关依赖注入部分:
 
<bean id="myResource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!--设置资源路径-->
        <property name="basenames">
            <list>
                <value>site/assad/i18n/resource</value>
            </list>
        </property>
</bean>
访问资源代码:
 
//根据xml配置文件,启动 spring 容器上下文
String[] configs = {"site/assad/springi18n/beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
//获取 MessageSource 的 bean
MessageSource messageSource = ctx.getBean("myResource",MessageSource.class);
//获取资源包中的国际化信息
String common1 = messageSource.getMessage("greeting.common",null,Locale.getDefault());
String common2 = messageSource.getMessage("greeting.common",null, Locale.US);
String common3 = messageSource.getMessage("greeting.common",null, Locale.CHINA);

ReloadableResourceBundleMessageSource 

该类相比ResourceBundleMessageSource的区别在于,可以定时刷新资源文件,以便在应用程序不重启的情况下感知资源文件的变化,适用于那些资源文件敏感变动而且需要长时间运行的应用程序;
示例代码模块site.assad.springi18n/I18nTest.class;site.assad.i18n/resource;site.assad.springi18n/beans.xml
beans.xml 中的相关依赖注入部分:
 
<bean id="myResource2" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!--设置资源路径-->
        <property name="basenames">
            <list>
                <value>site/assad/i18n/resource</value>
            </list>
        </property>
        <!--设置自动刷新时间-->
        <property name="cacheSeconds" value="10" />
</bean>
访问资源代码:
 
String[] configs = {"site/assad/springi18n/beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
MessageSource messageSource = ctx.getBean("myResource2",MessageSource.class);
String common1 = messageSource.getMessage("greeting.common",null,Locale.getDefault());
String common2 = messageSource.getMessage("greeting.common",null, Locale.US);
String common3 = messageSource.getMessage("greeting.common",null, Locale.CHINA);

容器级别提供国际化信息的访问

以上示例中 ResourceBundleMessageSource 和 ResourceBundleMessageSource 的装配和调用方式都是将 MessageSource 作为一个 bean 注入其他 bean 中,但实际应用情况下这是比较少见的做法(以上示例代码仅仅用于演示这2个类的装配,注入方式);

在实际使用国际化信息的场景中(Spring MVC的页面标签、Contrioller控制器等),往往会将 MessageSource 作为容器的基础设施向所有 bean 开放,即在大部分的使用场景下,会以容器级别注册 MessageSource
将 MessageSource 注册为容器级别,需要将该 MessageSource bean id 命名为 “messageSoucre” ,由于 ApplicationConext 实现了MessageSource 接口,可以直接通过 ApplicationContext 调用注册为容器级别的资源包;
详细代码见模块:site.assad.springi18n/I18nTest.class;site.assad.i18n/resource;site.assad.springi18n/beans.xml

beans.xml 中的相关依赖注入部分:
 
 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <!--设置资源路径-->
        <property name="basenames"> 
            <list>
                <value>site/assad/i18n/resource</value>
            </list>
        </property>
 </bean>
访问资源代码:
 
String[] configs = {"site/assad/springi18n/beans.xml"};
ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
//直接通过 ApplicationContext 获取资源
String common1 = ctx.getMessage("greeting.common",null,Locale.getDefault());
String common2 = ctx.getMessage("greeting.common",null, Locale.US);
String common3 = ctx.getMessage("greeting.common",null, Locale.CHINA);

※ 一个spring容器中只能存在一个命名为 “messageSource” 的bean,该bean默认注册为容器级别的 MessageSource;


通过 MessageSource 访问占位符参数化的资源

MessageSoucre 区别于 java.util.ResourceBundle ,本身已经支持访问占位符参数化的资源,不必借助 java.util.MessageFormat ;
示例代码模块:site.assad.springi18n/FmtI18nTest.class;site.assad.i18n/fmt_resource;site.assad.springi18n/beanFmt.xml

示例资源包 fmt_source.properties 
 
greeting.common=How are you!{0},today is {1,date,short}
greeting.morning=Good morning!{0},now is {1,time,short}
greeting.afternoon=Good afternoon!{0},now is{1,time,short}
MessageSource 注入的xml配置:
 
<beans ...>
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>site/assad/i18n/fmt_resource</value>
            </list>
        </property>
    </bean>
</beans>
访问参数化资源代码:
 
//加载Spring容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("site/assad/springi18n/beanFmt.xml");
//设置占位符参数
Object[] params = {"Al-assad",new Date()};
//获取资源键值
String common1 = ctx.getMessage("greeting.common", params,Locale.CHINA);
String morning1 = ctx.getMessage("greeting.morning", params,Locale.CHINA);
String afternoon1 = ctx.getMessage("greeting.afternoon", params,Locale.CHINA);
String common2 = ctx.getMessage("greeting.common", params,Locale.US);
String morning2 = ctx.getMessage("greeting.morning", params,Locale.US);
String afternoon2 = ctx.getMessage("greeting.afternoon", params,Locale.US);
System.out.println(common1+"\n"+morning1+"\n"+afternoon1+"\n"+common2+"\n"+morning2+"\n"+afternoon2);
/*output:
*   你好!Al-assad,今天是 17-12-1
    上午好!Al-assad,现在的时间是 下午3:48
    下午好!Al-assad,现在的时间是 下午3:48
    How are you!Al-assad,today is 12/1/17
    Good morning!Al-assad,now is 3:48 PM
    Good afternoon!Al-assad,now is3:48 PM
    */

原创粉丝点击