今天来说说Struts2 的另一个功能- 国际化,Struts2 的国际化是建立在Java 国际化的基础上的,一样是通过提供不同国家/ 语言环境的消息资源,然后通过ResourceBundle 加载指定的Locale 对应的资源文件,再取得该资源文件中指定key 对应的消息,整个过程与Java 程序的国际化完全相同,只是Struts2 框架对java 程序国际化进行了进一步的封装,从而简化了应用程序的国际化。
我们先来看看Java 的国际化:
Test.java:
package org.iflytek.test; import java.util.Locale; import java.util.ResourceBundle; /** * @author xudongwang 2011-10-31 * */ public class Test { public static void main(String[] args) { // ResourceBundle res = ResourceBundle.getBundle("app", Locale.CHINA); ResourceBundle res = ResourceBundle.getBundle("app", Locale.US); // app_en_US.properties // en表示语言,US表示国家 System.out.println(res.getString("welcome.msg")); } }
app_en_US.properties :
welcome.msg=hello,sir
app_zh_CN.properties :
welcome.msg=\u6b22\u8fce\u4f60\uff01
Struts2 内置国际化功能:
1、 自动创建 ResourceBundle 对象;
2、 从 http header 中自动创建 local 对象;
3、 为获得资源提供便利(标签库、工具类);
4、 提供层次化的资源分布(全局、 package 、 Action );
5、 通过拦截器实现( com.opensymphony.xwork2.interceptor.i1 8nInterceptor ),是一;
Struts2 的资源加载机制:
通过 TextProvider 实现资源文件查找和加载
Properties 文件匹配顺序为:
1、 与 Action 所在 package 下的类名称匹配;
2、 与 Action 实现接口名称匹配;
3、 与 Action 父类名称匹配;
4、 与 Action 实现 Model Driven 的 Model 类名称匹配;
注意这里可以到 struts2-core-2.1.8.1.jar-->org-->apache-->struts2-->default.properties 中查看;
Struts2 资源文件:
全局资源文件:
1、 首先要放在 src 目录下
2 、名称必须为 globalMessages_en.properties 和 globalMessages_zh.properties 等;
针对单个 Action 的资源文件:
1 、放在 /src/struts/demo/action 下,即和 Action 目录相同;
2 、名字为 Action 的类名 _en.properties 和 Action 的类名 _zh.properties 等;
在 Struts2 中需要做国际化的有: jsp 页面展示的信息、 Action 的错误信息、转换错误信息、校验错误信息。
在前面的 Struts2.2 Configuration 中提过配置国际化:
<constant name="struts.custom.i18n.resources" value="message"></constant>
具体步骤:
1、 编写 login_from .jsp:
<title><s:text name="title"/></title> <s:form action="login-form" namespace="/il8n"> <s:textfield name="user.username" key="username"> </s:textfield> <s:passwordname="user.password"label="%{getText('password')}"> </s:password> <s:submit key="submit"></s:submit> <s:text name="greeting" /> </s:form>
说明:
1 、 <s:text> 标签
2、 Form UI 标签的 key 属性
3 、 %{getText('key')}
2 、分别编写全局的国际化资源文件和单个的
单个的:
LoginAction_en.properties :
title=please login username=Username password=Password submit=Login
LoginAction_zh.properties :
title=\u8BF7\u767B\u9646 username=\u5E10\u53F7 password=\u5BC6\u7801 submit=\u767B\u9646
全局的:
globalMessages_en.properties :
greeting = welcome language=Language
globalMessages_zh.properties
greeting = \u6B22\u8FCE language=\u8BED\u8A00
3 、 struts.xml:
<constant name="struts.custom.i18n.resources" value="globalMessages" /> <package name="il8n" namespace="/il8n" extends="struts-default"> <action name="login-form" class="struts.demo.action.LoginAction" method="form"> <result name="success">/login_form.jsp</result> </action> </package>
注意:因为上面有全局的国际化资源文件,所以需要配置 <constant name="struts.custom.i18n.resources" value="globalMessages" /> ,这里和 struts1 不同的是在 Struts1 中的 struts 配置文件中还要有 <message-resources parameter="myResource">
</message-resources> 而 Struts2 是由于其内置的拦截器起来作用;
4 、 LoginAction.java:
package struts.demo.action; import struts.demo.bean.User; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionSupport; /** * @author xudongwang 2011-5-19 * */ public class LoginAction extends ActionSupport { private User user; getter/setter public String form() { return Action.SUCCESS; } }
注意上面的要继承 ActionSupport 因为这个类下有国际化属性
i18nInterceptor 拦截机制:
1 、从 request parameter 中查找 request_locale
2 、如果不存在,则从 session 中查找 WW_TRANS_I18N_LOCALE
3 、如果不存在则从 ActionContext 获得服务器的 locale
4 、设置找到的 locale 为 ActionContext 的默认 locale
在上面的国际化的基础上实现不同语言间的切换:
在上面的基础上继续编写
select-language.jsp :
<title><s:text name="title" /></title> <body> <s:bean name="struts.demo.bean.LocaleProvider" var="lp" /> <s:form id="langForm"> <s:select name="request_locale" list="#lp.enableLocales" value="#lp.currentLocale" listKey="key" listValue="value" key="language" onchange="document.getElementById('langForm').submit()" /> </s:form> </body>
LocaleProvider.java
package struts.demo.bean; import java.util.HashMap; import java.util.Map; import com.opensymphony.xwork2.ActionContext; /** * @author xudongwang 2011-5-19 * */ public class LocaleProvider { private static Map<String, String> enableLocales = new HashMap<String, String>(); static { enableLocales.put("zh", "中文"); enableLocales.put("en", "English"); } public Map<String, String> getEnableLocales() { return enableLocales; } public String getCurrentLocale() { return ActionContext.getContext().getLocale().getLanguage(); } }
资源文件在上面已经包含了
在 login_form.jsp 上只要多引用 select-language.jsp 即可,最终变为 ;
<title><s:text name="title"/></title> <body> <s:include value="/select-language.jsp"></s:include> <s:form action="login-form" namespace="/il8n"> <s:textfield name="user.username" key="username"></s:textfield> <s:password name="user.password" label="%{getText('password')}"></s:password> <s:submit key="submit"></s:submit> <s:text name="greeting" /> </s:form>