Struts2的国际化(一)-国际化资源文件的配置及国际化信息的访问
一、概述:
1)国际化是一种技术:在程序设计领域,把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化。
2)本地化是一个动作:与国际化对应的是本地化,指让一个具备国际化支持的应用程序支持某个特定的地区。
3)Struts2 国际化是建立在 Java 国际化基础上的:
>为不同国家/语言提供对应的消息资源文件
>Struts2 框架会根据请求中包含的Locale 加载对应的资源文件
>通过程序代码取得该资源文件中指定 key 对应的消息
二、如何配置国际化资源文件?
国际化资源文件有以下4种配置方式:
I. Action 范围资源文件: 在Action类文件所在的路径下建立名为 ActionName_language_country.properties 的文件。
II. 包范围资源文件: 在包的根路径下建立文件名为 package_language_country.properties 的属性文件,
一旦建立,处于该包下的所有 Action 都可以访问该资源文件。注意:包范围资源文件的 baseName就是package,不是Action所在的包名。
III. 全局资源文件
> 命名方式: basename_language_country.properties(文件建立在src目录中)
> struts.xml中配置: <constant name="struts.custom.i18n.resources" value="baseName"/>
注意:全局资源文件中的baseName是自己指定的,但是文件名中的baseName要与struts.xml中的配置对应上。
Ⅳ. 临时指定资源文件:使用<s:i18n.../> 标签的 name 属性指定临时的国际化资源文件。(该方式不经常使用)
三、国际化资源文件加载的顺序如何呢 ?
结论:离当前 Action 较近的将被优先加载。
以下为详细的加载顺序描述,了解一下:
假设我们在某个 ChildAction 中调用了getText("username"):
(1) 加载和 ChildAction 的类文件在同一个包下的系列资源文件 ChildAction.properties
(2) 加载 ChildAction 实现的接口 IChild,且和 IChild 在同一个包下 IChild.properties 系列资源文件。
(3) 加载 ChildAction 父类 Parent,且和 Parent 在同一个包下的 baseName 为 Parent.properties 系列资源文件。
(4) 若 ChildAction 实现 ModelDriven 接口,则对于getModel()方法返回的model 对象,重新执行第(1)步操作。
(5) 查找当前包下 package.properties 系列资源文件。
(6) 沿着当前包上溯,直到最顶层包来查找 package.properties 的系列资源文件。
(7) 查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。
(8) 直接输出该key的字符串值。
四、 如何在页面上和 Action 类中访问国际化资源文件的 value 值?
I. 在 Action 类中,若 Action 实现了 TextProvider 接口, 则可以调用其 getText() 方法获取 value 值。
> 通过继承 ActionSupport 的方式间接的实现TextProvider接口。
II. 页面上可以使用 s:text 标签;对于表单标签可以使用表单标签的 key 属性值
> 若有占位符,则可以使用 s:text 标签的 s:param 子标签来填充占位符
> 可以利用标签和 OGNL 表达式直接访问值栈中的属性值(对象栈 和 Map 栈)
五、示例
示例一:在非simple主题下,在页面上key的方式直接从资源文件中获取对应的value值。
1)JSP页面主要代码如下(JSP页面名称为“i18n.jsp”):
1 <s:form action=""> 2 <!-- 这里label属性的方式是把label值写死在标签中的 --> 3 <s:textfield name="username" label="Username"></s:textfield> 4 <!-- key 的方式是直接上资源文件中获取 value 值 --> 5 <s:textfield name="username" key="username"></s:textfield> 6 <s:password name="password" key="password"></s:password> 7 <s:submit key="submit"></s:submit> 8 </s:form>
2)对应的全局资源文件如下:
其中,i18n.properties和i18n_en_US.properties文件的内容均为:
username=UserName
password=Password
submit=Submit
i18n_zh_CN.properties文件的内容为:
username=\u7528\u6237\u540D (用户名)
password=\u5BC6\u7801 (密码)
submit=\u63D0\u4EA4 (提交)
3)struts.xml中的配置内容为:
<!-- 配置国际化资源文件,注意:这里value值可以是任意的,与资源文件对应即可 --> <constant name="struts.custom.i18n.resources" value="i18n"></constant>
在Tomcat中部署后运行结果如下图所示,可以看出,在非simple主题下,在页面上使用key属性可以方便的访问到相应的国际化资源文件的值。
将浏览器语言环境设置为中文时的结果如下图: 将浏览器语言环境设置为英语时的结果如下图:
,
4)在非simple主题下,在表单标签中,我们还可以在label属性中使用OGNL表达式,使label标签也能够获取国际化信息,
修改JSP页面代码如下,即将label属性中的值改为OGNL表达式:%{getText('username')}:
<s:textfield name="username" label="%{getText('username')}"></s:textfield>
★★之所以 label 标签使用 %{getText('username')} 的方式就也可以从国际化资源文件中获取 value 值,是因为此时在对象栈中有DefaultTextProvider 的一个实例,该对象中提供了访问国际化资源文件的 getText() 方法,同时还需要通知 Struts2 框架 label 中放入的不再是一个普通的字符串,而是一个 OGNL 表达式,所以使用 %{} 把 getText()包装起来, 以强制进行 OGNL 解析。
示例二:在simple主题下,在页面上<s:text>标签从资源文件中获取对应的value值。
由于在simple主题下,label属性与key属性不再起作用,因此,这时需要使用<s:text>标签来访问国际化资源文件中的信息。
修改JSP页面代码如下:
1 <s:form action="" theme="simple"> 2 <s:text name="username"/>:<s:textfield name="username"></s:textfield><br> 3 <s:text name="username"/>:<s:textfield name="username"></s:textfield><br> 4 <s:text name="password"/>:<s:password name="password"></s:password><br> 5 <%-- submit中要在value中使用OGNL表达式--%> 6 <s:submit key="submit" value="%{getText('submit')}"></s:submit> 7 </s:form>
示例三:访问有占位符的国际化资源信息
1)JSP页面中通过<s:text>标签的字标签<s:param>来填充占位符,代码如下:
1 <s:text name="time"> 2 <s:param value="date"></s:param> 3 </s:text>
并添加index.jsp页面,以便访问Action,代码如下:
<a href="testI18n">Test I18N</a>
2)Java代码如下,其中包含了在Action中访问国际化资源文件信息的方法,并对date属性进行了赋值。
★★★若 Action 类继承了 ActionSupport ,则可调用 TextProvider 接口的 getText 方法。
1 package com.atguigu.struts2.i18n.app; 2 import java.util.Arrays; 3 import java.util.Date; 4 import com.opensymphony.xwork2.ActionSupport; 5 public class TestI18nAction extends ActionSupport { 6 private Date date = null; 7 public Date getDate() { 8 return date; 9 } 10 public void setDate(Date date) { 11 this.date = date; 12 } 13 public String execute() throws Exception { 14 date = new Date(); 15 //1. 在 Action 中访问国际化资源文件的 value 值 16 String username = getText("username"); 17 System.out.println(username); 18 //2. 带占位符的 19 String time = getText("time", Arrays.asList(date)); 20 System.out.println(time); 21 return SUCCESS; 22 } 23 }
3)在struts.xml中配置Action:
<action name="testI18n" class="com.atguigu.struts2.i18n.app.TestI18nAction"> <result>/i18n.jsp</result> </action>
4)在全局国际化资源文件中加入如下信息:
time=Time:{0} <===> time=\u65F6\u95F4:{0} (时间:{0})
部署后运行的结果如下图:
<===>
5)对于有占位符的国际化信息,我们还可以直接在国际化资源文件中使用OGNL表达式的方式来获取对应的参数★★★
JSP页面中添加如下代码:
<s:text name="time2"></s:text>
在全局国际化资源文件中添加如下信息:
time2=Time:${date} <===> time2=\u65F6\u95F4:${date} (时间${date})
★★★注:${}这是OGNL表达式在properties文件中的格式,同样,在struts.xml等中使用时也是使用${},而在JSP页面中则是%{}的格式。(参汤阳光-OA中的说明)
注:以上内容对于其它的配置方式同样起作用,不再一一列举。