« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9692162 建立时间:2004年12月20日 |

| |
[java语言]spring技术手册阅读笔记(四) 使用Resource 原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2006/10/22 15:37:09 |
资源包包含特定于语言环境的对象。当程序需要一个特定于语言环境的资源时(如 String),程序可以从适合当前用户语言环境的资源包中装入它。以这种方式可以编写很大程度上独立于用户语言环境的程序代码,它将资源包中大部分(如果不是全部)特定于语言环境的信息隔离开来。spring的ApplicationContext继承了ResourceLoader。它的子接口WebApplicationContext 也就是继承了ResourceLoader,可以使用getResource方法访问资源文件。如果判断指定资源文件存不存在,使用exists()方法。例如 直接读取web下的文件,注意web的根目录不是classes,classes是类的根目录 Resource res=getWebApplicationContext().getResource("WEB-INF/classes/View.properties");也可以用 Resource res=getWebApplicationContext().getResource("classpath:View.properties");处理消息ApplicationContext继承了MessageSource接口,这样你就可以用getMessage读取多语言版本的资源文件,使用ResourceBundleMessageSource来获取国际化消息。ctx.getMessage("chengang", null, null);有三个参数: 第一个是资源文件的键值; 第二个是资源文件字符串的参数,由于本字符串没有参数,所以用一个null(后面给出了一个用到字符串参数的实例); 第三个是一个java.util. Locale类型的参数。参数为null,则表示根据使用者的语言环境来选择Locale,因为我用的是中文版的windows,所以在取字符串时它自动选择了messages_zh_CN.properties资源文件。 这其中还有一个控制点在JVM,JVM会根据当前操作系统的语言环境进行相应处理,我们可以通过在JVM启动参数中追加“-Duser.language=zh_CN”来设定当前JVM语言类型,通过JVM级的设定,也可以实现自动切换所使用的资源文件类型。 所以这里面的控制语言的方式有三种:从最低层的操作系统的Locale设定,到更上一层的JVM的Locale设定,再到程序一级的Locale设定。举个例子定义文件<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename"> <value>View</value> </property> </bean> ResourceBundleMessageSource是Spring的一个Message类。也可用ReloadableResourceBundleMessageSource类,此类可以提供不用重启即可重新加载资源文件的特性(前者对资源文件只加载一次)。对于那种即使修改资源文件的需求,ReloadableResourceBundleMessageSource比较合适,每次他都加载。basenames是一个字符串数组,可以写入多个。view的名字遵循sun的规范
从概念上讲,getBundle 使用下列策略来搜索并实例化资源包:
getBundle 使用基本名称、指定的语言环境和默认语言环境(从 Locale.getDefault 获得)来生成候选包名称 序列。如果指定语言环境的语言、国家/地区和变量都是空字符串,则基本名称就是惟一的候选包名称。否则,从指定语言环境 (language1, country1, and variant1) 和默认语言环境 (language2, country2, and variant2) 的属性值生成下列序列: baseName + "_" + language1 + "_" + country1 + "_" + variant1 baseName + "_" + language1 + "_" + country1 baseName + "_" + language1 baseName + "_" + language2 + "_" + country2 + "_" + variant2 baseName + "_" + language2 + "_" + country2 baseName + "_" + language2 baseName
省略最后部分为空的候选包名称。例如,如果 country1 是一个空字符串,则省略第二个候选包名称。
getBundle 然后在候选包名称上进行迭代,找到第一个可实例化 为实际资源包的候选包名称。对于每个候选包名称,它都试图创建资源包: 首先,它试图使用候选包名称加载一个类。如果可以找到这样的类并使用指定的类加载器将其加载,并且如果此类的分配与 ResourceBundle 兼容并可从 ResourceBundle 访问它,还可以将其实例化,则 getBundle 创建此类的一个新实例,并使用它作为结果资源包。 否则,getBundle 会试图搜索属性资源文件。它从候选包名称生成一个路径名,方法是用 "/" 替换所有的 "." 字符并追加字符串 ".properties"。然后试图用 ClassLoader.getResource 找到一个具有此名称的“资源”(注意,getResource 中的“资源”与资源包中的内容没有任何关系,它只是一个数据的容器,如文件)。如果它找到一个“资源”,则会试图用其内容创建一个新的 PropertyResourceBundle。如果成功,那么此实例就成为结果资源包。
如果未找到结果资源包,则抛出 MissingResourceException。
一旦找到了结果资源包,那么它的父链就是已实例化的。getBundle 在可以获得的候选包名称中进行迭代,获得名称的方法是从结果资源包的包名称中连续移除变量、国家/地区和语言(每次都用前缀 "_")。正如上面所述,省略最后组件是空字符串的候选包名称。对于每个候选包名称,它都会试图实例化一个资源包,如上所述。只要能够成功,它就用新的资源包调用先前已实例化资源包的 setParent 方法,除非先前已实例化的资源包已经有非 null 的父包。
getBundle 实现可能会缓存已实例化的资源包并多次返回相同的资源包实例。只要结果资源包及其父链的选择符合上面的描述,则还可能改变实例化资源包的序列。
baseName 参数应该是一个完全限定类名。但是,为了与早期的版本兼容,Sun 的 Java 2 运行时环境并不对此进行检查,所以可通过指定路径名(使用 "/")而不是完全限定类名(使用 ".")来访问 PropertyResourceBundle。
示例:提供了下面的类和属性文件:MyResources.class、MyResources_fr_CH.properties、MyResources_fr_CH.class、MyResources_fr.properties、MyResources_en.properties、MyResources_es_ES.class。所有文件的内容都是有效的(也就是 ".class" 文件是 ResourceBundle 的公共非抽象子类,".properties" 文件的语法正确)。默认的语言环境是 Locale("en", "GB")。
如下所示,使用给出的语言环境参数值调用 getBundle,实例化资源包: Locale("fr", "CH"):结果 MyResources_fr_CH.class,父 MyResources_fr.properties,父 MyResources.class Locale("fr", "FR"):结果 MyResources_fr.properties,父 MyResources.class Locale("de", "DE"):结果 MyResources_en.properties,父 MyResources.class Locale("en", "US"):结果 MyResources_en.properties,父 MyResources.class Locale("es", "ES"):结果 MyResources_es_ES.class,父 MyResources.class 从未使用 MyResources_fr_CH.properties 文件,因为它由 MyResources_fr_CH.class 隐藏了。
也可以使用占位符,spring使用MessageeFormat解决的userLogin=User {0} login at {1}这个文件spring会自动加载,你不用处理 ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml");
Object[] arguments = new Object[] {"良葛格", Calendar.getInstance().getTime()};
System.out.println( context.getMessage("userLogin", arguments, Locale.US)); System.out.println( context.getMessage("userLogin", arguments, Locale.TAIWAN));如果没有占位符,取得中文 String keyvalue=(String)getWebApplicationContext().getMessage(keyname,null,Locale.CHINESE); |
|
|