首页 > 代码库 > Struts2中的国际化

Struts2中的国际化

1为什么需要国际化呢??
几年之前,应用程序开发者能够考虑到仅仅支持他们本国的只使用一种语言(或者有时候是两种)和通常只有一种数量表现方式(例如日期、数字、货币值)的应用。然而,基于web技术的应用程序的爆炸性增长,以及将这些应用程序部署在Internet或其它被广泛访问的网络之上,已经在很多情况下使得国家的边界淡化到不可见。这种情况转变成为一种对于应用程序支持国际化(internationalization,经常被称做"i18n",因为18是字母"i"和字母"n"之间的字母个数)和本地化的需求。国际化是商业系统中不可或缺的一部分,所以无论您学习的是什么Web框架,它都是必须掌握的技能。
 
2什么叫国际化呢?
在程序设计领域, 把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化.
 
3什么叫本地化呢??
•与国际化对应的是本地化, 指让一个具备国际化支持的应用程序支持某个特定的地区
•Struts2 国际化是建立在 Java 国际化基础上的:
 

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中的国际化