最爱Java

书山有路勤为径,学海无涯苦作舟

2010年11月11日

    Java程序的国际化主要通过三个类完成:

    java.util.ResourceBundle:用于加载一个资源包。

    java.util.Locale:对应一个特定的国家/区域、语言环境。

    java.text.MessageFormat:用于消息格式化。

    而资源文件的命名方式主要有三种:baseName_language_country.properties、baseName_language.properties和baseName.properties。

    以下的程序可以得到Java所支持的语言和国家:

public class LocalList {
    
public static void main(String[] args){
        Locale[] localeList 
= Locale.getAvailableLocales();
        
for (int i=0;i<localeList.length;i++){
            System.out.println(localeList[i].getdisplayCountry() 
+ "=" + localeList[i].getCountry() + " " + localeList[i].getDisplayLanguage() + "=" + localeList[i].getLanguage());
        }

    }

}

    使用国际化的代码如: 

public class Hello{
    
public static void main(String[] args){
        Locale myLocale 
= Locale.getDefault();
        ResourceBundle bundle 
= ResourceBundle.getBundle("mess",myLocale);
        System.out.println(bundler.getString(
"hello"));
    }

}

    如果在资源文件中,存在例如msg = Hello,{0}!Today is {1}.这样需要程序动态插入参数的文本,则需要使用MessageFormat类的format()方法。

    除了使用资源文件,我们也可以使用类文件来代替资源文件。使用Java文件代替资源文件的Java文件必须满足:1。类名必须是baseName_language_country,这与属性文件的命名相似。2。该类必须继承ListResourceBundle,并重写getContents方法,该方法返回Object数组。该数组的每一个项都是key-value对。

public class MyResource_zh_CN extends ListResourceBundle {
    
//定义资源
    private final Object myData[][] = {
        
{"msg","类文件消息:{0},您好!今天是{1}"}
    }
;
    @Override
    
public Object[][] getContents(){
        
return myData;
    }

}


    对于简体中文的Locale,ResourceBundler搜索资源的顺序是:

    baseName_zh_CN.class;baseName_zh_CH.properties;baseName_zh.class;baseName_zh.properties;baseName.class;baseName.properties

 

    Struts2访问国际化消息,主要有3种方式:1)JSP页面输出国际化消息,可以使用Struts2的<s:text.../>标签,该标签可以指定一个name属性,该属性就是资源文件中的key。2)在Action中,可以使用ActionSupport类的getText方法,该方法可以接受一个name参数,指定了国际化资源文件中的key。3)表单元素的Label,可以为表单标签指定一个key属性,这个key指定了国际化资源文件的key。

     对于带占位符的国际化消息,在Action中,则需要使用getText(String key, String[] args)来处理,其中args就是参数列表;而在页面中,则需要为<s:text.../>标签指定<s:param.../>子标签。如:

<s:text name="welcomeMsg">
    
<s:param><s:property value="username"></s:param>
</s:text>


   在Struts2中,还有一种更加简单的表达方式。我们可以在资源文件中写例如这样的表达式:failTip=${username},对不起,您不能登录!,通过使用表达式,可以从ValueStack中取出username属性值,自动填充到消息资源中。这在Action中很常用。

    对于一个大型应用而言,国际化资源文件的管理也是一个非常浩大的工程。为了能更好的分而治之,Struts2允许针对不同的模块、不同Action来组织国家化资源文件。

     为Strut2应用指定包范围资源文件的方法是:在包的跟路径下建立多个文件名为package_language_country.properties的文件,一旦建立了这个系列的国际化资源文件,应用中处于该包下的所有Action都可以访问该资源文件。

    例如一个Action为codes\packageScope\src\lee\action\LoginAction.java,那么我们可以提供package_zh_CN.properties和package_en_US.properties两个文件放在codes\packageScope\src\lee目录下,那么这两个文件就能被lee包及lee包下所有子包内的Action所能访问。

    同时,我们也可以为LoginAction单独指定一份国际化资源文件。即在codes\packageScope\src\lee\action目录下,分别建立LoginAction_zh_CN.properties和LoginAction_en_US.properties两个文件。

    有时候,处于某种特殊的原因,我们需要临时指定资源文件,那么就需要使用<s:i18n.../>来充当<s:text.../>标签的父标签了。如:

<s:i18n name="tmp">
    
<s:text name="loginPage"/>
</s:i18n>

<s:i18n name="tmp">
    
<s:form action="login">
        
<s:textfield name="username" key="user"/>
        
<s:textfield name="password" key="pass"/>
        
<s:submit key="login"/>
    
</s:form>
</s:i18n>


    加载资源文件的顺序:

  1.     优先加载系统中保存在ChildAction的类文件相同位置,且baseName为ChildAction的系列资源文件。
  2.     如果在1)中找不到key对应的消息,且ChildAction有父类ParentAction,则加载系统中保存在ParentAction的类文件相同位置,且baseName为ParentAction的系列资源文件。
  3.     如果2)中找不到key对应的消息,且ChildAction有实现接口IChildAction,则加载系统中保存在IChildAction的类文件相同位置,且baseName为IChildAction的系列资源文件。
  4.     如果3)中找不到key对应的消息,且ChildAction有实现接口ModelDriven(即使用模型驱动模式),则对于getModel()方法返回的model对象,重新执行1)步操作。
  5.     如果在4)中找不到key对应的消息,则查找当前包下baseName为package的系列资源文件。
  6.     如果在5)中找不到key对应的消息,则沿着当前包上溯,直到最顶层包来查找baseName为package的系列资源文件。
  7.     如果在6)中找不到key对应的消息,则查找struts.custom.i18n.resources常量指定baseName的系列资源文件。
  8.     如果经过上面步骤一直找不到key对应的消息,将直接输出该key的字符串值

      对于在JSP中访问国际化消息,则简单很多,可以分为两种形式:

      1)对于使用<s:i18n.../>标签作为父标签的<s:text.../>标签,将直接从<s:i18n.../>标签指定的国际化资源文件中加载指定key对应的消息,如果没有,则读取struts.custom.i18n.resources常量指定baseName的系列文件。如果还没有,直接输出key。

     2)对于没有使用<s:i18n.../>标签作为父标签的<s:text.../>标签,则直接读取struts.custom.i18n.resources常量指定baseName的系列文件。如果没有,直接输出key。

    Struts2中, 我们可以通过ActionContext.getContext().setLocale(Locale arg)设置用户的默认语言。同时在Struts2 的defaultStack拦截栈中,i18n拦截器也能设置默认语言。i18n在执行Action方法前,会自动查找一个名为request_locale的参数。如果这个参数存在,则拦截器会将其转换成Locale对象,并设为默认的Locale。同时,这个Locale对象会保存在Session的名为WW_TRANS_I18N_LOCALE的属性中。一旦用户的Session中有WW_TRANS_I18N_LOCALE属性,则属性指定的Locale将会作为浏览器的默认Locale。因此,用户也可利用此功能来开发自行选择语言的功能。

posted @ 2010-11-11 22:16 Brian 阅读(317) | 评论 (0)编辑 收藏

公告


导航

<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(4)

随笔分类

随笔档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜