struts2的国际化(一)
国际化又被称为I18N,因为国际化的英文是Internationalization,它以I开头,以N结尾,中间有18个字母。一个国际化的程序,当它运行在本地机器时,需要根据本地机器的语言和地区设置显示相应的字符,这个过程就叫做本地化(Localization),通常简称为:L10N
说到struts2中的国际化,不得不先提到java程序的国际化,因为struts2再怎么变化,也是将最基础的东西进行了封装,让用户用起来更方便。同时,封装也带来一个问题:当运用struts2中的国际化时出错了,无法调试,无法确定错误的位置。
1.java国际化程序
在java中编写国际化程序主要通过两个类完成: java.util.Locale类和java.util.ResourceBundle抽象类。
Locale类用天提供本地信息,通常称它为语言环境。不同的语言,不同的国家和地区采用不同的Locale对象来表示。
ResourceBundle类称为资源包,包含了特定于语言环境的资源对象。当程序需要一个特定于语言环境的资源时(如字符串资源),程序可以从适合当前用户语言环境的资源包中加载它。采用这种方式,可以编写独立于用户语言环境的程序代码,而与特定语言环境相关的信息则通过资源包来提供。
1.1 Locale类
Java.util.Locale类的常用构造方法如下:
public Locale(String language)
public Locale(String language,String country)
其中language表示语言,它的取值是由ISO-639定义的小写的、两个字母组成的语言代码。
其中country表示国家或地区,它的取值由ISO-639定义的大写的、两个字母组成的代码。
例:应用于中国的locale :Locale locale = new Locale(“zh”,”CN”);
应用于美国的locale:Locale locale = new Locale(“en”,”US”);
应用于英国的locale:Locale locale = new Locale(“en”,”GB”);
1.2 java.util.ResourceBundle类
要获取某个资源包,可以调用java.util.ResourceBundle类中的静态方法getBundle(),如下
public static final ResourceBundle getBundle(String baseName) :根据基名得到资源包,使用系统缺省的Locale对象。
public static final ResourceBundle getBundle(String baseName,Locale locale):根据基名和Locale对象得到资源名。
public final String getString(String key):得到相应语言版本的字符串
例如:Locale locale = new Locale(“zh”,”CN”);
bundle = ResourceBundle. getBundle(“MyResource”,locale);
String name = bundle.getString(“name”);
注意:假设Locale为使用中文的中国大陆地区,资源包基名为MyResource ,在网上搜到了很多关于国际化的资料,基本上一致说ResourceBundle类的静态方法getBundle(String baseName)按照下列的顺序查找资源包:
MyResource_zh_CN.class
MyResource_zh_CN.properties
MyResource_zh.class
MyResource_zh.properties
MyResource.class
MyResource.properties
我测试了一下,测试环境如下:windowsxp 中文系统,eclipse+GlassFish,设置Locale loc = new Locale("ar","LB");
我有以下资源文件:
global_en_US.properties
global_zh_CN.properties
global.properties(默认)
按照以上说法,bundle.getString(“name”)得到的应该是global.properties中对应的字符串,实际情况并不是这样的,得到的却是global_zh_CN.properties中name对应的字符串。
为了搞清楚情况,我进行了debug。在ResourceBundle. getBundle方法上面,有以下说明,大致的意思如下:
step 1:根据设定的locale,寻找对应的资源包,如果找到,返回相应的资源包。如果没有找到,step 2。
step 2:寻找a base bundle(默认的资源文件),如果找到了,step 3,如果没有找到step 4
step 3:阻塞a base bundle,判断the candidate locale list中除了base bundle外,是否还存在其他的bundle,如果不存在,则返回a base bundle,如果存在,step 4
step 4:调用control.getFallbackLocale("foo.bar.Messages", Locale.getDefault()),返回current target locale。step 5
step 5:根据current target locale,再一次寻找资源包,如果找到到,返回相应的资源包,如果没有找到,但是存在a base bundle,返回a base bundle,否则抛出MissingResourceException。
在测试列子中没有找到loc对应的资源文件,但找到了global_zh_CN.properties,因此返回的是global_zh_CN.properties中对应的字符串,假如不存在global_zh_CN.properties,才会返回global.properties中对应的字符串。
接下来的内容见struts2的国际化(二)