Struts2 国际化资源表达式用法

来源:互联网 发布:python正则匹配ip地址 编辑:程序博客网 时间:2024/05/21 19:32

下面略述com.opensymphony.xwork2.ActionSupport.getText()方法
public String getText(String aTextName)
说明:Gets a messages based on a message key,or null if no message is found
Parameters:aTextName-the resource bundle key that is to be searched for

得到一个基于key的消息,如果没有找到这个消息则返回null
参数:aTextName是在资源包寻找到的所匹配的key
小结:该方法用来完成国际化,接收的参数即资源包中的key,返回资源包中的value
public String getText(String aTextName,List args)
说明:Gets a message based on a key using the supplied args,as defined in MessageFormat
使用提供的一个被定义在MessageFormat中的参数args得到一个基于key的消息
小结:即此时资源包的key的值可以带参数,即{0}占位符,该参数由List类型的args提供
换句话说,此时可以传递一些运行时的参数,使得消息的产生是动态的
另外还有个与该方法功能相同的public String getText(String key,String[] args)
只不过List参数的方法可接收Object参数,而数组参数的方法则只能接收String
实际上Object类型的参数真正输出到页面时,也是调用toString()转换成字符串
public String getText(String aTextName,String defaultValue)
说明:Gets a message based on a key,if the message is not found,a supplied default value is returned
小结:即当在资源包中找不到key时,就会返回defaultValue


Struts2里面国际化资源文件的三个存活范围
Struts2提供了更精细化的资源文件定义方式,可分全局的局部的
而局部的国际化资源文件又分为两种情况,分别是:包级别类级别
包级别资源文件自然要在相应包下建立,它的命名是固定的package_zh_CN.properties
若存在相同key,那么包级别中的提示信息要高于全局资源文件中的提示信息
这就好似Java一样,若定义了同名的成员变量和局部变量,那么成员变量将被覆盖掉
类级别资源文件同样要建立在相应包下,它的命名类似于LoginAction_zh_CN.properties
类级别的提示信息更加具体,因此类级别的提示信息要高于包级别资源文件的提示信息


类级别和包级别在应用中的触发点
若要在表单中进行国际化信息的显示,则应去掉<s:form/>theme="simple"属性
然后将姓名输入域改为<s:textfield name="username" key="username.xml.invalid"/>
访问页面时,会在姓名位置显示包级别提示信息,即package_zh_CN.properties中的
点击Submit时会在姓名位置显示类级别别提示信息,即RegisterAction_zh_CN.properties中的
点击Submit后,表单便与在struts.xml中设定的Action关联在一起,故显示类级别提示信息
所以当使用类级别国际化文件时,必须经过Action才能生效,才能按照预定的进行国际化
若未经Action而直接访问JSP页面,则无法显示类级别的国际化消息,这一点和Struts1.X是不一样的


在国际化资源文件中嵌套OGNL表达式
国际化资源文件中的内容示例如下
login.text = 登录
login.title = %{getText("login.text")}页面
那么在页面中显示login.title国际化消息时,就会显示:登录页面


页面中国际化的显示
<s:text name="key"/>会自动按照范围到资源文件中查找name所指定的key
然后输出Key所对应的Value,若Key不存在,则将name值原封不动的输出
并且它也是可以动态传递参数的,这时需要在该标签中嵌套<s:param/>标签
<s:label key=""/>在输出国际化信息时,会自动在国际化文本后面加上一个多余的冒号
通过查看页面源文件发现:使用<s:label/>输出的国际化信息位于HTML的<label/>标签内
使用<s:text/>输出的国际化信息则是一些单纯的文本
<s:i18n name=""/>用来明确的指定所使用的临时的国际化资源文件
并且该临时资源文件默认与struts.xml处于同一目录下,亦可在name中指定其存放路径
它的name值用来指定所要读取的国际化资源文件,然后再嵌套<s:text/>标签就可以输出指定的key值了
<s:param/>中显示国际化信息如在<s:param value="%{getText('login.tip')}"/>
<s:param/>中接收Action属性如<s:param value="%{username}"/>
Struts2表单标签的key属性通常用来输出国际化信息,可以在key值中传一个OGNL表达式
label属性中放的是字符串,所以也可以使用%{}输出国际化信息,如下所示
<s:property value="getText('key')"/>或者<s:textfield label="%{getText('key')}"/>
另外关于<s:radio/>标签的国际化显示,如下所示
<s:radio list="#{1:getText('i18n.sex.male') ,0:getText('i18n.sex.female')}" name="sex" value="1" key="i18n.sex"/>
这个时候就不用再写成%{getText('i18n.sex.male')}了,也就是说可以把%{}去掉了
由于<s:textfield label="%{getText('key')}"/>label默认使用的是字符串,所以要加上%{}
而在<s:radio/>list属性里面本身已经有{}符号了,说明它已经是一个OGNL表达式了
所以在<s:radio list=“#{}”/>中就没必要再使用%{}


浅述Struts2国际化的实现过程
Struts2的I18nInterceptor拦截器会拦截所有的Action,它主要做的事情为
从客户端发送过来的请求参数中寻找是否存在名为request_locale的参数
若有,则将request_locale的value转化为locale保存起来
该locale是保存在以WW_TRANS_I18N_LOCALE所命名的session里面的
详见源码的第124行session.put(attributeName, locale)
其中attributeName即79行的protected String attributeName = DEFAULT_SESSION_ATTRIBUTE
和第75行的public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE"
于是便可通过这种方式实现一个选择页面所显示的语言环境的功能
比如选择中文,那么就可以将request_locale设置为zh_CN
如果我们不做任何配置的话,客户端是不会发送request_locale参数的
它默认会用request的getLocale()方法得到默认locale,将其存放在session中
这样就使得以后客户的所有操作都是在同一个国际化的环境下执行
就不需要我们每一次都手工判断用户的国际化环境了


接下来为大家展示示例代码

首先是struts.xml文件

[xhtml] view plaincopyprint?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
  3. "http://struts.apache.org/dtds/struts-2.1.dtd">
  4. <struts>
  5. <constantname="struts.custom.i18n.resources"value="message"/>
  6. <packagename="struts2.1"extends="struts-default">
  7. <actionname="internationalization"class="com.jadyer.action.InternationalizationAction">
  8. <result>loginSuccess.jsp</result>
  9. <resultname="input">internationalization.jsp</result>
  10. </action>
  11. </package>
  12. </struts>

然后是web.xml文件

[xhtml] view plaincopyprint?
  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  6. <filter>
  7. <filter-name>struts2</filter-name>
  8. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  9. </filter>
  10. <filter-mapping>
  11. <filter-name>struts2</filter-name>
  12. <url-pattern>/*</url-pattern>
  13. </filter-mapping>
  14. <welcome-file-list>
  15. <welcome-file>internationalization.jsp</welcome-file>
  16. </welcome-file-list>
  17. </web-app>

用于显示国际化信息的internationalization.jsp页面

[xhtml] view plaincopyprint?
  1. <%@ page language="java"pageEncoding="UTF-8"%>
  2. <%@ taglib prefix="s"uri="/struts-tags"%>
  3. <strong>
  4. <ahref="internationalization.action?request_locale=zh_CN"><s:textname="internationalization.jsp.CHINESE"/></a>|
  5. <ahref="internationalization.action?request_locale=en_US"><s:textname="internationalization.jsp.ENGLISH"/></a>
  6. </strong>
  7. <hr/>
  8. <STRONG>
  9. <FONTcolor="green">
  10. <s:i18nname="com.jadyer.action.temp">
  11. <s:textname="hello">
  12. <s:param>玄玉</s:param>
  13. </s:text>
  14. </s:i18n>
  15. </FONT>
  16. </STRONG>
  17. <hr/>
  18. <h4>初始姓名和密码为<fontcolor="blue"><b>admin</b></font><fontcolor="blue"><b>jadyer</b></font></h4>
  19. <s:fielderrorcssStyle="font-size:20px;color:red;text-align:left;font-weight:bold"/>
  20. <s:formaction="internationalization"theme="simple">
  21. <tableborder="9">
  22. <tr>
  23. <td><s:propertyvalue="getText('internationalization.jsp.username')"/></td>
  24. <td><s:textfieldname="username"/></td>
  25. </tr>
  26. <tr>
  27. <td><s:textname="internationalization.jsp.passwrod"/></td>
  28. <td><s:passwordname="password"/></td>
  29. </tr>
  30. <tr>
  31. <td></td>
  32. <tdalign="center"><s:submit/></td>
  33. </tr>
  34. </table>
  35. </s:form>

访问成功后跳转到loginSuccess.jsp页面

[xhtml] view plaincopyprint?
  1. <%@ page pageEncoding="UTF-8"%>
  2. <h2>Login Success</h2>

然后是用到的InternationalizationAction.java类

[java] view plaincopyprint?
  1. package com.jadyer.action;
  2. import com.opensymphony.xwork2.ActionSupport;
  3. @SuppressWarnings("serial")
  4. publicclass InternationalizationAction extends ActionSupport {
  5. private String username;
  6. private String password;
  7. //关于username和password属性的getter和setter方法略
  8. @Override
  9. public String execute() throws Exception {
  10. if("admin".equals(this.getUsername().trim())&&"jadyer".equals(this.getPassword().trim())){
  11. return SUCCESS;
  12. }else{
  13. this.addFieldError("username",this.getText("username.password.error"));
  14. return INPUT;
  15. }
  16. }
  17. /**
  18. * List list = new ArrayList();
  19. * list.add(username);
  20. * this.addFieldError(this.getText("username.invalid", list));
  21. * 建议使用String[]数组的方式。因为它本身放的就是String类型的参数,很方便
  22. * 使用addActionError()实现国际化的方式与addFieldError()是一样的,这里就不再举例了
  23. */
  24. @Override
  25. publicvoid validate() {
  26. if (null == username || username.length() < 4 || username.length() > 10) {
  27. this.addFieldError("username",this.getText("username.invalid",new String[]{username}));
  28. }
  29. }
  30. }

用来测试<s:i18n>、<s:text>、<s:param>标签组合使用的temp_zh_CN_en_US.properties国际化资源文件

[c-sharp] view plaincopyprint?
  1. hello = /u4F60/u597D/u3010{0}/u3011/u3002/u8FD9/u662F/u4F7F/u7528Struts2/u7684i18n/u6807/u7B7E/u5D4C/u5957text/u6807/u7B7E/u8F93/u51FA/u7684/u7ED3/u679C
  2. hello = Hello/u3010{0}/u3011/u3002Thisis used the Struts2 i18n with text tag to result

最后是用到的全局的message_zh_CN.properties和message_en_US.properties国际化资源文件

[java] view plaincopyprint?
  1. internationalization.jsp.CHINESE = /u4E2D/u6587/u7248
  2. internationalization.jsp.ENGLISH = /u82F1/u6587/u7248
  3. internationalization.jsp.passwrod = /u5BC6/u7801
  4. internationalization.jsp.username = /u7528/u6237
  5. username.invalid = /u7528/u6237/u540D"{0}" /u586B/u5199/u4E0D/u6B63/u786E
  6. username.password.error = /u7528/u6237/u540D/u6216/u5BC6/u7801/u4E0D/u6B63/u786E
  7. internationalization.jsp.CHINESE = Chinese
  8. internationalization.jsp.ENGLISH = English
  9. internationalization.jsp.passwrod = password
  10. internationalization.jsp.username = username
  11. username.invalid = username"{0}" invalid
  12. username.password.error = username or password error
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 app在下载东西时被停用了怎么办 买东西填错地址 但已签收怎么办 网购手机受骗后电话打不通怎么办 淘宝买的东西发错了怎么办 淘宝上买的东西发错了怎么办 淘宝上买的东西发多了怎么办 淘宝上买的东西出现问题怎么办 淘宝买东西未收到货显示签收怎么办 网上一张车票两人同时付款了怎么办 微信付款时显示银行卡被锁定怎么办 微信忘记支付密码怎么办没有银行卡 支付宝赏金扫码支付不行怎么办 网购收货时发现货物已破损怎么办 货物丢失了不承认调查出来了怎么办 小米商城已签收未收到了怎么办 网购的一只荷兰猪现在怎么办 中通快递的掌中通好评怎么办 唯品会快递被签收却没收到货怎么办 拼多多快递签收了但没收到货怎么办 顺丰代收签收成功要强制退款怎么办 淘宝付了钱如果商家没货了怎么办 别人拿走我的货不给钱怎么办 快递出途中损坏签单后才发现怎么办 顾客支付宝少付了钱人走了怎么办 顾客通过收钱码付的钱少了怎么办 寄顺丰快递收件人号码填错了怎么办 京东退货售后说是有划痕怎么办 手机上快递员软件签收错了怎么办 苹果手机进网许可证丢了怎么办 作废的普票发票联丢失怎么办 想退换货但是发票丢了怎么办 快递没有当面验货造成的丢件怎么办 退货卖家收货验货说有问题怎么办 没当着快递人员面验货少货怎么办 微信绑定的银行了被快捷支付怎么办 银行支付到微信支付里的钱怎么办 微信绑定银行忘支付密码忘了怎么办 微信桂林银行不可以支付怎么办 微信忘记支付密码和银行卡号怎么办 京东商城迟迟不通过退货审核怎么办 网上购物想退款商家要我拒收怎么办