Struts2也可以允许用户自行选择程序语言。而且,因为Struts2的支持,在程序中自行选择语言环境将变得更加简单。
<interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="profiling"/> <interceptor-ref name="scoped-model-driven"/> <interceptor-ref name="model-driven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="static-params"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack>i18n拦截器在执行Action方法前,自动查找请求中的一个名为request_locale的参数。如果该参数存在,拦截器就将其作为参数,并转换成Locale对象,并将其设为用户默认的Locale(代表语言/国家环境)。
public class Locales { //因为本实例也需要实现国际化,所以使用current作为用户当前的Locale private Locale current; //取得用户当前Locale的setter方法 public void setCurrent(Locale cur) { this.current = cur; } //取得本系统所支持的全部语言 public Map<String, Locale> getLocales() { //将当前系统支持的全部语言保持在Map对象中 Map<String, Locale> locales = new Hashtable<String, Locale>(); ResourceBundle bundle = ResourceBundle.getBundle("messageResource" , current); //添加当前系统支持的语言,key是系统支持语言的显示名字,value是系统支持语言的Locale实例 locales.put(bundle.getString("usen"), Locale.US); locales.put(bundle.getString("zhcn"), Locale.CHINA); return locales; } }在上面JavaBean中,我们使用了一个Map对象来保存所有用户支持的语言,该Map对象的key是所支持语言的显示名字,而该Map对象的value是所支持语言的Locale实例。应用支持语言的显示名字,也是通过国际化消息来生成的。
<!-- 使用lee.Locales创建locales实例 --> <s:bean id="locales" name="lee.Locales"> <!-- 为locales实例这种current参数值 --> <s:param name="current" value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"/> </s:bean>上面标签创建了lee.Locales类的locales实例,并为该实例传入了current参数值,设置该参数值时使用了三目运算符,先判断SESSION_LOCALE是否为空,如果该SESSION_LOCALE为空,则返回ValueStack中locale属性值(即用户浏览器设置的Locale);如果SESSION_LOCALE不为空,则返回该SESSION_LOCALE的值(即用户选择的Locale)。
<!-- 将用户Session中的“WW_TRANS_I18N_LOCALE”属性值设置成SESSION_LOCALE。 --> <s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>下面是该selectlanguage.jsp页面的代码:
<%@taglib prefix="s" uri="/struts-tags"%> <script type="text/javascript"> function langSelecter_onChanged() { document.getElementById("langForm").submit(); } </script> <!-- 将用户Session中的“WW_TRANS_I18N_LOCALE”属性值设置成SESSION_LOCALE。 --> <s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/> <!-- 使用lee.Locales创建locales实例 --> <s:bean id="locales" name="lee.Locales"> <!-- 为locales实例这种current参数值 --> <s:param name="current" value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"/> </s:bean> <!-- 让用户选择语言的表单 --> <form action="<s:url/>" id="langForm" style="background-color:#bbbbbb; padding-top: 4px; padding-bottom: 4px;"> <!-- 输出国际化提示 --> <s:text name="languag"/> <!-- 使用s:select标签迭代locales实例的locales Map属性 --> <s:select label="Language" list="#locales.locales" listKey="value" listValue="key" value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE" name="request_locale" id="langSelecter" onchange="langSelecter_onChanged()" theme="simple"/> </form>
languag=选择语言 usen=美式英语 zhcn=简体中文在英文资源文件中增加如下三项:
languag=Select Lanuage usen=American English zhcn=Simplified Chinese
<!-- 使用通配符号定义Action的name --> <action name="*"> <!-- 将请求转发该WEB-INF/jsp路径下同名的JSP页面 --> <result>/WEB-INF/jsp/{1}.jsp</result> </action>
<!-- 包含让用户自行选择程序语言的页面 --> <s:include value="selectlanguage.jsp"/>在任何页面中增加了上面代码后,该页面就能允许用户自行选择语言。通常,我们只需要在应用的第一个页面让用户选择程序语言,后续页面直接使用该语言即可。
资源文件的命名:basename_language_country.properties
(1)baseName_zh_CN.class (2)baseName_zh_CN.properties (3)baseName_zh.class (4)baseName_zh.properties (5)baseName.class (6)baseName.properties
<message key="username.xml.invalid"/>
JSP页面的国际化:
<s:text name="addUser"/>
struts.xml
<constant name="struts.custom.i18n.resources" value="baseName"/>或
struts.properties
struts.custom.i18n.resources=baseName
(1)JSP页面:<s:text name="key"/> (2)Action类中:使用ActionSupport类的getText方法。 (3)表单元素的Label里:为表单元素指定一个key属性
Struts2中提供了如下两种方式来填充消息字符串中的占位符
(1)JSP页面,在<s:text.../>标签中使用多个<s:param.../>标签来填充消息中的占位符。 (2)Action中,在调用getText方法时使用getText(String aTextName,List args)或getText(String key, String[] args)方法来填充占位符。
如下在消息资源中使用表达式
succTip=${username}, 欢迎, 您已经登录!在上面的消息资源中,通过使用表达式,可以从ValueStack中取出该username属性值,自动填充到该消息资源中。
(1)加载全局资源文件: <constant name="struts.custom.i18n.resources" value="baseName"/> (2)包范围资源文件 :为Struts2指定包范围资源文件的方法是,在包的根路径下建立多个文件名为package_language_country.properties的文件,一旦建立了这个系列的国际化资源文件,应用中处于该包下的所有Action都可以访问该资源文件。需要注意的是上面的包范围资源文件的baseName就是package,不是Action所在的包名。 (3)Action范围资源文件:在Action类文件所在的路径建立多个文件名为ActionName_language_country.properties的文件。 (4)临时指定资源文件:<s:i18n.../>标签的name属性指定临时的国际化资源文件
(1)优先加载系统中保存在ChildAction的类文件相同位置,且baseName为ChildAction的系列资源文件。 (2)如果在(1)中找不到指定key对应的消息,且ChildAction有父类ParentAction,则加载系统中保存在ParentAction的类文件相同位置,且 baseName为ParentAction的系列资源文件。 (3)如果在(2)中找不到指定key对应的消息,且ChildAction有实现接口IChildAction,则加载系统中保存在IChildAction的类文件相同位置,且 baseName为IChildAction的系列资源文件。 (4)如果在(3)中找不到指定key对应的消息,且ChildAction有实现接口ModelDriven(即使用模型驱动模式),则对于getModel()方法返回的model对象, 重新执行第(1)步操作。 (5)如果在(4)中找不到指定key对应的消息,则查找当前包下baseName为package的系列资源文件。 (6)如果在(5)中找不到指定key对应的消息,则沿着当前包上溯,直到最顶层包来查找baseName为package的系列资源文件。 (7)如果在(6)中找不到指定key对应的消息,则查找struts.custom.i18n.resources常量指定baseName的系列资源文件。 (8)如果经过上面的步骤一直找不到key对应的消息,将直接输出该key的字符串值。
(1)对于使用<s:i18n.../>标签作为父标签的<s:text.../>标签、表单标签的形式: a、将从<s:i18n.../>标签指定的国际化资源文件中加载指定key对应的消息。 b、如果在a中找不到指定key对应的消息,则查找struts.custom.i18n.resources常量指定baseName的系列资源文件。 c、如果经过上面步骤一直找不到该key对应的消息,将直接输出该key的字符串值。 (2)如果<s:text.../>标签、表单标签没有使用<s:i18n.../>标签作为父标签: 直接加载struts.custom.i18n.resources常量指定baseName的系列资源文件。如果找不到该key对应的消息,将直接输出该key的字符串值。
<%@ page language="java" contentType="text/html; charset=GBK"%> <%@taglib prefix="s" uri="/struts-tags"%> <script. type="text/javascript"> function langSelecter_onChanged() { document.getElementById("langForm").submit(); } </script> <%-- 设置SESSION_LOCALE为用户session中的WW_TRANS_I18N_LOCALE属性值 --%> <s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/> <%-- 使用lee.Locales创建locales实例 --%> <s:bean id="locales" name="lee.Locales"> <%-- 为locales实例传入current参数值,如果SESSION_LOCALE为空,则返回ValueStack中locale属性值(即用户浏览器设置的Locale) --%> <s:param name="current" value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"/> </s:bean> <%-- 让用户选择语言的表单 --%> <form. action="<s:url/>" id="langForm" style="background-color:#bbbbbb; padding-top: 4px; padding-bottom: 4px;"> <s:text name="languag"/> <s:select label="Language" list="#locales.locales" listKey="value" listValue="key" value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE" name="request_locale" id="langSelecter" nchange="langSelecter_onChanged()" theme="simple"/> </form>
<s:include value="selectlanguage.jsp"/>
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.custom.i18n.resources" value="messageResource"/> <constant name="struts.i18n.encoding" value="GBK"/> <package name="lee" extends="struts-default"> <!-- 使用通配符定义Action的name --> <action name="*"> <!-- 将请求转发给/WEB-INF/jsp/路径下同名的JSP页面 --> <result>/WEB-INF/jsp/{1}.jsp</result> </action> </package> </struts>
转载自:http://blog.csdn.net/zhangweikai966/article/details/7581384
http://www.cnblogs.com/langlang/archive/2010/01/14/1647627.html
实例详解:http://wawa129.iteye.com/blog/1182648
http://www.cnblogs.com/lihuiyy/archive/2013/03/14/2958782.html
远离详解:http://blog.csdn.net/zollty/article/details/8710718