[原创]java WEB学习笔记69:Struts2 学习之路-- 消息处理与国际化,概述,配置国际资源文件,访问国际化消息,通过超链接切换语言
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用
内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。
本人互联网技术爱好者,互联网技术发烧友
微博:伊直都在0221
QQ:951226918
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.概述:
1)在程序设计领域, 把在无需改写源代码即可让开发出来的应用程序能够支持多种语言和数据格式的技术称为国际化.
2)与国际化对应的是本地化, 指让一个具备国际化支持的应用程序支持某个特定的地区
3)Struts2 国际化是建立在 Java 国际化基础上的:
- 为不同国家/语言提供对应的消息资源文件
- Struts2 框架会根据请求中包含的 Locale 加载对应的资源文件
- 通过程序代码取得该资源文件中 指定 key 对应的消
2.如何配置国际化资源文件
1) Action 范围资源文件:在Action类文件所在的路径建立名为 ActionName_language_country.properties 的文件
2) 包范围资源文件:在包的根路径下建立文件名为package_language_country.properties 的属性文件,一旦建立,处于该包下的所有 Action 都可以访问该资源文件。注意:包范围资源文件的 baseName 就是package,不是Action所在的包名。
3) 全局资源文件
- 命名方式: basename_language_country.properties
- struts.xml : <constant name="struts.custom.i18n.resources" value="baseName"/>
了解:
- struts.propertiesstruts.custom.i18n.resources=baseName
- 临时指定资源文件:<s:i18n.../> 标签的 name 属性指定临时的国际化资源文件
4)国际化资源文件加载的顺序如何?离当前 Action 较近将优先被加载
1 假设我们在某个 ChildAction 中调用了getText("username"):
2 (1)加载和 ChildAction 的类文件在同一个包下的系列资源文件 ChildAction.properties
3 (2)加载 ChildAction 实现的接口 IChild,且和 IChildn 在同一个包下 IChild.properties 系列资源文件。
4 (3)加载 ChildAction 父类 Parent,且和 Parent 在同一个包下的 baseName 为 Parent.properties 系列资源文件。
5 (4) 若 ChildAction 实现 ModelDriven 接口,则对于getModel()方法返回的model 对象,重新执行第(1)步操作。
6 (5) 查找当前包下 package.properties 系列资源文件。
7 (6) 沿着当前包上溯,直到最顶层包来查找 package.properties 的系列资源文件。
8 (7) 查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。
9 (8) 直接输出该key的字符串值。
1 username=UserName 2 password=Password 3 submit=Submit 4 time=Time:{0}
1 username=UserName 2 password=Password 3 submit=Submit 4 time=Time:{0}
1 username=\u7528\u6237\u540D 2 password=\u5BC6\u7801 3 submit=\u63D0\u4EA4 4 time=\u65F6\u95F4:{0}
3.如何在页面上和Action 类中访问国际化资源文件的value 值:
1)在Aciton 类中,若Action 实现了TextProvider 接口,则可以调其getText() 方法获取value 值
> 通过继承ActionSupport 的方式
1 package com.jason.struts2.i18n;
2
3 import java.util.Arrays;
4 import java.util.Date;
5
6 import com.opensymphony.xwork2.ActionSupport;
7
8 public class TestI18nAction extends ActionSupport {
9
10 /**
11 * @Fields:serialVersionUID
12 */
13 private static final long serialVersionUID = 1L;
14 private Date date = null;
15
16 public Date getDate() {
17 return date;
18 }
19
20 public void setDate(Date date) {
21 this.date = date;
22 }
23
24 @Override
25 public String execute() throws Exception {
26
27 date = new Date();
28 // 1.在Actoin 中访问国际化资源文件的value 值
29 String username = getText("username");
30 System.out.println(username);
31
32 // 2.带占位符
33 String time = getText("time", Arrays.asList(date));
34
35 System.out.println(time);
36 return SUCCESS;
37 }
38
39 }
2)页面上可以使用<s:text> 标签;对于表单标签可以使用标签的Key 属性值。
> 若有占位符,则可以使用<s:text> 标签的<s:param> 子标签来填充多个占位符
> 若当前页面来自于Action 则可以直接访问Action 中的属性值
> 可以利用标签 和 OGNL 表单式直接访问值栈中的属性,(对象栈 额 map栈)
simple主题下:使用<s:text>
1 <s:form action="" theme="simple">
2 <!--label 方式 是把label 写死在标签里 -->
3 <s:textfield name="username" label="UserName"></s:textfield>
4 <!--
5 若label 标签使用 %{getText('xxx')} 的方式就可以从国际化资源文件中获取value值。因为此时,在对象栈中,
6 有DefaultTextProvizer 的一个实例,该对象中提供了访问国际化资源文件的getText() 方法,
7 同时还需要告知 Struts2 框架 label 中放入的不在是一个普通的字符,而是一个OGNL 表达式,所以使用%{},强制进行OGNL 解析
8
9 -->
10
11 <!--
12 对于simple 主题 可以使用 <s:text name=""/> 标签来访问国际化资源文件中的value 值
13 -->
14 <s:text name="username"/><s:textfield name="username" label="%{getText('userName')}"></s:textfield>
15
16 <!-- 直接上资源文件中获取 value 值 -->
17 <s:text name="username"/><s:textfield name="username" key="username"></s:textfield>
18 <s:text name="password"/><s:textfield name="password" key="password"></s:textfield>
19
20 <s:submit key="submit" value="%{getText('submit')}"></s:submit>
21 </s:form>
其他的使用 key 来获取资源文件的value值
1 <s:form action="" >
2 <!--label 方式 是把label 写死在标签里 -->
3 <s:textfield name="username" label="UserName"></s:textfield>
4 <!--
5 若label 标签使用 %{getText('xxx')} 的方式就可以从国际化资源文件中获取value值。因为此时,在对象栈中,
6 有DefaultTextProvizer 的一个实例,该对象中提供了访问国际化资源文件的getText() 方法,
7 同时还需要告知 Struts2 框架 label 中放入的不在是一个普通的字符,而是一个OGNL 表达式,所以使用%{},强制进行OGNL 解析
8
9 -->
10 <s:textfield name="username" label="%{getText('userName')}"></s:textfield>
11
12 <!-- 直接上资源文件中获取 value 值 -->
13 <s:textfield name="username" key="username"></s:textfield>
14 <s:textfield name="password" key="password"></s:textfield>
15
16 <s:submit key="submit" ></s:submit>
17 </s:form>
4.通过超链接切换语言
1)关键之处在于知道Struts2 框架 是如何确定local 对象的
2)可以通过阅读 i18n 拦截器知道
i18n 拦截器运行流程
> Struts2 使用 i18n 拦截器 处理国际化,并且将其注册在默认的拦截器中
> 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 对象。
具体实现:只需要在超链接的后面附着 request_locale 的请求参数:语言_国家代码
<a href="testI18n.acttion?request_locale=en_US">英文</a>
<a href="testI18n.acttion?request_locale=zh_CN">中文</a>
注意:超链接必须是一个strut2 的请求,即使 i18n 拦截器工作