首页 > 代码库 > Struts2中的国际化
Struts2中的国际化
1. 国际化的目标
1). 如何配置国际化资源文件
I. Action 范围资源文件: 在Action类文件所在的路径建立名为 ActionName_language_country.properties 的文件
II. 包范围资源文件: 在包的根路径下建立文件名为 package_language_country.properties 的属性文件,
一旦建立,处于该包下的所有 Action 都可以访问该资源文件。注意:包范围资源文件的 baseName 就是package,不是Action所在的包名。
II和I不推荐使用吖,因为一个项目中往往有大量的Action,不可能大量的去配置国际化文件吧!所以一般推荐III种
III. 全局资源文件
> 1命名方式: basename_language_country.properties---->例如命名为:i18n.properties
basename_language_country.properties文件的书写格式:
属性名(要与页面或者Action的属性名相匹配)=value
属性名(要与页面或者Action的属性名相匹配)=str{0}------str:代表可以使任意字符
配置i18n.properties文件后,我们一般会根据需要,再配置其他国家的.properties文件,这里英文和中文的
i18n.properties代码如下:
1 username=UserName2 password=Password3 submit=Submit4 time=Time:{0}5 time2=Time\:${date}
中文默认是:i18n_zh_CN.properties
代码如下://因为编码格式的原因,下面\u7528\u6237\u540D是表示中文字符来的
1 username=\u7528\u6237\u540D2 password=\u5BC6\u78013 submit=\u63D0\u4EA44 5 time=\u65F6\u95F4\:{0}6 time2=\u65F6\u95F4\:${date}
英文默认是:i18n_en_US.properties
代码如下:
1 username=UserName2 passwword=Password3 submit=Submit4 5 time=Time:{0}6 time2=Time\:${date}
{0}就是一个占位符,占位符的作用就是占着一个位置,以后可以放入我们想放的东西
> 2 struts.xml <constant name="struts.custom.i18n.resources" value="http://www.mamicode.com/baseName"/>
这样全局国际化资源就配置完毕了
IV. 国际化资源文件加载的顺序如何呢 ? 离当前 Action 较近的将被优先加载.(就近原则)
假设我们在某个 ChildAction 中调用了getText("username"):
(1) 加载和 ChildAction 的类文件在同一个包下的系列资源文件 ChildAction.properties
(2) 加载 ChildAction 实现的接口 IChild,且和 IChildn 在同一个包下 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的字符串值。
2). 如何在JSP页面上 和 Action 类中访问国际化资源文件的 value 值
I..在JSP 页面上可以使用 s:text 标签;
ps:对于表单标签可以使用表单标签的 key 属性值Example:<s:textfield name="username" key="username"></s:textfield>,但是若<s:form>标签的模板设为simple就不能这样引用,所以我们一般推荐使用<s:text>标签
使用<s:text>访问时:
<s:text name="username"/>
这样就可以访问到国际化资源库的属性了
> 若有占位符, 则可以使用 s:text 标签的 s:param 子标签来填充占位符
1 time=Time:{0}----这里是国际资源文件里的
2 <s:text name="time">
3 <s:param value="http://www.mamicode.com/date"></s:param>---》<s:param>标签代表占位符放的东西,可以是对象,也可以是字符,若放入的是对象,记得要Action类中声明
4 </s:text>
> 可以利用标签和 OGNL 表达式直接访问值栈中的属性值(对象栈 和 Map 栈)
1 <s:text name="%{getText(‘username‘)}"></s:text>//使用值栈里的实例的方法获得了值
II在 Action 类中. 若 Action 实现了 TextProvider 接口, 则可以调用其 getText() 方法获取 value 值
> 通过继承 ActionSupport 的方式。
package com.atguigu.struts2.i18n.app;import java.util.Arrays;import java.util.Date;import com.opensymphony.xwork2.ActionSupport;public class TestI18nAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private Date date = null; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String execute() throws Exception { date = new Date(); //1. 在 Action 中访问国际化资源文件的 value 值 String username = getText("username"); System.out.println(username); //2. 带占位符的 String time = getText("time",date.toLocaleString());//date.toLocaleString()就代表占位符要放的东西 System.out.println(time); return SUCCESS; }}
------------------------------------
上面什么都配置好了,问题又来了,那Struts2是怎样调用i18n_zh_CN.properties和i18n_en_US.properties文件的呢??
这两个文件我都没有去配置任何东西,但是当浏览器的语言改变时却调用我这两个文件???
下面就是对于国际化资源化文件调用的分析
1 i18n拦截器在执行Action方法前,自动查找请求中一个名为request_locale的参数。如果该参数存在,拦截器就将其作为参数,转换成Locale对象,
并将其设为用户默认的Locale(就是当前浏览器默认的Locale---所以我们这里虽然没有配置i18n_zh_CN.properties和i18n_en_US.properties文件,但是根据浏览器的locale能自动的匹配我这个两个文件)(代表国家/语言环境)。
除此之外,i18n拦截器还会将上面生成的Locale对象保存在用户Session的名为WW_TRANS_I18N_LOCALE的属性中。
一旦用户Session中存在一个名为WW_TRANS_I18N_LOCALE的属性,则该属性指定的Locale将会作为浏览者的默认Locale。
3). 实现通过超链接切换语言.
I. 关键之处在于知道 Struts2 框架是如何确定 Local 对象的 !
可以通过阅读 I18N 拦截器知道. 具体确定 Locale 对象的过程:
> Struts2 使用 i18n 拦截器 处理国际化,并且将其注册在默认的拦截器栈中---default-stack
> i18n拦截器在执行Action方法前,自动查找在请求中一个名为 request_locale 的参数。
如果该参数存在,拦截器就将其作为参数,转换成Locale对象,并将其设为用户默认的Locale(代表国家/语言环境)。
并把其设置为 session 的 WW_TRANS_I18N_LOCALE 属性
> 若 request 没有名为request_locale 的参数,则 i18n 拦截器会从 Session 中获取 WW_TRANS_I18N_LOCALE 的属性值,
若该值不为空,则将该属性值设置为浏览者的默认Locale
> 若 session 中的 WW_TRANS_I18N_LOCALE 的属性值为空,则从 ActionContext 中获取 Locale 对象。
流行历程图:
IV. 具体实现: 只需要在超连接的后面附着 request_locale 的请求参数, 值是 语言国家 代码.
<a href="http://www.mamicode.com/testI18n.action?request_locale=en_US">English</a>
<a href="http://www.mamicode.com/testI18n.action?request_locale=zh_CN">中文</a>
> 注意: 超链接必须是一个 Struts2 的请求, 因为需要 i18n 拦截器工作!
本文章源码:http://files.cnblogs.com/jeremy-blog/Struts2-7-i18n.zip
Struts2中的国际化