Struts2的国际化是建立在java的国际化基础上的。通过提供不同国家或者语言环境的消息资源,然后通过ResourceBundle加载指定Locale对应的资源文件,再获取该资源文件中的指定key对应的消息。Struts2框架对这一过程进行了进一步的封装,简化了应用程序的国际化。它可以为jsp,Action,全局范围提供不同的国际化资源,因此维护的时候可以分开维护。Struts2的国际化可以按照以下步骤进行:加载国际化资源文件、输出国际化。
action范围、包范围的国际化资源会被系统自动加载,jsp范围,全局范围的需要使用标签库,配置常量的方式手动加载。视图页面的国际化消息需要struts2标签库输出,action中的消息需要ActionSupport的getText()方法完成。
资源文件需要是properties,并且放在src下。命名规则必须严格按照baseName_language_country.properties。比方说我们要实现与login相关的国际化,就要建立login_zh_CN.properties和login_en_US.properties这两个文件或者更多。然后两个文件中对于相同的key字段,要给出中英文value。其中,value值可以使用占位符,比如:你好{0},至于怎么传参数,稍后再解释。
视图页面的国际化
jsp中指定国际化资源需要通过《s:i18n/》标签。之所以叫i18n,因为internationalization一共18个字母。当text标签在il8n里面时,text就会加载il8n指定的国际化资源文件。当form在i18n里面时,表单里的key(就是普通jsp里的value,显示在页面的内容)就会从国际化中提取信息。资源文件是一个properties。放在src或其子目录下。jsp中的i18n标签里面的name属性指定properties文件位置。如下代码能够加载位于packagename包下面的baseName为myinternational的一系列国际化资源文件。
<s:i18n name="packagename.myinternational">
Action与包的国际化
当对action或者action的输入校验进行国际化时,可以为action单独指定一份国际化资源文件。在action的路径下建立多个名为ActionName_language_country.properties的文件。这些国际化文件会被系统自动加载。在action中直接使用父类的getText方法获取指定key的value值。ps:校验文件中使用国际化value,可以用message子元素的可以属性。为每个action都制定一份国际化文件太麻烦了,在包下建立package_language_country.properties一系列文件,这些文件会被系统自动加载。
全局国际化
在struts.xml中或者struts.properties中配置struts.custom.i18n.resource常量就可以加载全局国际化资源文件。该常量的值为一系列全局国际化文件的baseName。如果baseName为example的话,在struts.properties中加入如下代码:
struts.custom.i18n.resource=example
此时应该注意国际化文件应该与配置文件同路径。全局国际化消息资源可以被整个应用的所有组件使用。
带占位符的国际化消息
当国际化资源中包含形如{0},{1}的占位符时,这些占位符必须要被一些参数所代替。jsp中的占位符会被s:param元素中的值所代替。第几个param就代替第几个占位符。
<s:text name="username"></s:text> <s:text name="welcomg"> <s:param><s:property value="username"/></s:param> <s:param>S{d}</s:param> </s:text>
而对应的welcomg资源文件中的值应该为
welcome={0}, 你好,现在时间是:{1}-----------------------------------------welcome={0}, Hello, now is {1}
除此之外,在国际化消息中还可以使用表达式。使用这种方式,就不需要在调用国际化消息时,额外为占位符赋值。比如:
current username=当前用户为:${username}
这种方式的工作原理是:系统会在ValueStack中取出该username的值,然后填充到国际化消息中。
加载资源文件顺序
假设说一个action要加载它需要的action文件,那么顺序如下:
- 先找它自己独享的,也就是baseName与action同名的。
- 如果没有,就找它的父类的独享。
- 如果没有,就找action的接口的独享。
- 如果还没有,找action所在的包的独享文件。
- 如果还没有,顺着包往上找,最后还没没有的话,就去找全局的。
- 如果还没有的话,就直接输出key属性的值。
假设说要为jsp加载国际化文件,如果有s:i18n作为父标签,顺序如下:
- 找s:i18n指定的nameBase。
- 如果没有,就去找全局的。
- 如果还没有,那没办法了,直接找出key的字符串数值。
如果没有使用s:i18n作为父标签,则直接加载全局资源文件。找不到就直接输出key属性的值。