随笔 - 117  文章 - 72  trackbacks - 0

声明:原创作品(标有[原]字样)转载时请注明出处,谢谢。

常用链接

常用设置
常用软件
常用命令
 

订阅

订阅

留言簿(7)

随笔分类(130)

随笔档案(123)

搜索

  •  

积分与排名

  • 积分 - 152563
  • 排名 - 390

最新评论

[标题]:[原]Struts2-国际化
[时间]:2009-8-9
[摘要]:Struts2 internationalization
[关键字]:浪曦视频,Struts2应用开发系列,WebWork,Apache,国际化,i18n,multi-lingual,多语言,资源文件
[环境]:struts-2.1.6、JDK6、MyEclipse7、Tomcat6
[作者]:Winty (wintys@gmail.com) http://www.blogjava.net/wintys

[正文]:
    首先要在struts.xml中配置全局国际化文件Basename为message:
    <constant name="struts.custom.i18n.resources" value="message" />
1、JSP页面的国际化
a.普通信息国际化
在src目录下新建message.properties(optional,没有zh_CN和en_US等资源文件时就会找message.properties),新建对应的中文和英文properties为:
message_zh_CN.properties、message_en_US.properties。

/StrutsHelloWorld/src/message_en_US.properties:
wintys.i18n.title=Register

/StrutsHelloWorld/src/message_zh_CN.properties:
wintys.i18n.title=注册

在JSP页面中使用:
<s:text name="wintys.i18n.title" />

在浏览器中访问时,会根据不同的Locale显示相应的国际化信息。

b.表单信息国际化
同样是在message_zh_CN.properties、message_en_US.properties中配置key=value。

JSP页面中的表单:
<s:form action="...">
    ......
    <s:textfield name="name" key="wintys.i18n.name" />
    ......
</s:form>

没有国际化时是用<s:textfield label="name" />,国际化后应该用<s:textfield name="name" key="wintys.i18n.name" />

注意,国际化时,表单的theme不能为simple

c.国际化标签<s:i18n />
除了可以使用<s:text />国际化,还可以使用<s:i18n />。<s:text />会在message_XX_XX.properties中查找key(如果有包级别、类级别的properties,则会优先应用包级别和类级别的properties)。而<s:i18n name="basename"/>则在basename指明的文件(/src/basename_XX_XX.properties)中查找key。

/StrutsHelloWorld/src/messagefile_en_US.properties:
wintys.i18n.desc = description
wintys.i18n.addition = {0} , additional information


/StrutsHelloWorld/src/messagefile_zh_CN.properties:
wintys.i18n.desc = "u8BF4"u660E
wintys.i18n.addition ={0} , "u989D"u5916"u4FE1"u606F

使用如下:
<s:i18n name="messagefile">
    <s:text  name="wintys.i18n.desc"/><br/>
    <s:text name="wintys.i18n.addition">
        <s:param>Hello</s:param>
    </s:text>
</s:i18n>


2、Action中的国际化
    ActionSupport类中有一系列重载的getText()方法,用于国际化。
一句话:addActionError(getText("wintys.i18n.name.invalid"));。addFieldError()也类似。

/StrutsHelloWorld/src/wintys/struts2/i18n/I18nAction.java:
package wintys.struts2.i18n;
import com.opensymphony.xwork2.ActionSupport;
/**
 *
 * @author Winty (wintys@gmail.com)
 * @version 2009-8-9
 * @see http://wintys.blogjava.net
 */
public class I18nAction extends ActionSupport {
    private static final long serialVersionUID = 2188344424923390101L;
    
    private String name;
    private int age;
    
    //此处省略了getter and setter
        
    @Override
    public void validate() {
        if(name == null || "".equals(name.trim()) ){
            //before i18n
            //addActionError("name should not be empty");
            
            //after i18n
            //带参数也可以:getText(String key , String[] args);
            addActionError(getText("wintys.i18n.name.invalid"));
        }
    }
    
    @Override
    public String execute() throws Exception {    
        return SUCCESS;
    }
}

3、验证框架的国际化
一句话:<message key="wintys.i18n.age.conversion.error" />。
还可以使用<message>${getText("name.invalid")}</message>。

/StrutsHelloWorld/src/wintys/struts2/i18n/I18nAction-validation.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
          "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
          "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
 <validators>
     <field name="age">
         <field-validator type="conversion" short-circuit="true">
             <!-- before i18n:<message>age conversion error</message> -->
             <message key="wintys.i18n.age.conversion.error" />
         </field-validator>
         <field-validator type="int">
             <param name="min">1</param>
             <param name="max">150</param>
             <!-- <message>age range: ${min} ~ ${max}</message> -->
             <message key="wintys.i18n.age.exceed.range"/>
         </field-validator>
     </field>
 </validators>

4、局部国际化文件
    前面所定义的key都是在全局国际化文件message_XX_XX.properties中定义的,也可以定义包级别和类级别的properties,其中key的优先级是:类级别>包级别>全局。

    a.包级别properties
        在包中新建"package_XX_XX.properties"。
/StrutsHelloWorld/src/wintys/struts2/i18n/package_en_US.properties:
wintys.i18n.name = Name
wintys.i18n.age = Age
wintys.i18n.submit = Submit

/StrutsHelloWorld/src/wintys/struts2/i18n/package_zh_CN.properties:
wintys.i18n.name = \u59D3\u540D
wintys.i18n.age = \u5E74\u9F84
wintys.i18n.submit = \u63D0\u4EA4

    b.类级别properties
        在包中新建"类名_XX_XX.properties"。
/StrutsHelloWorld/src/wintys/struts2/i18n/I18nAction_en_US.properties:
wintys.i18n.name = Name(class level)
wintys.i18n.age = Age(class level)
wintys.i18n.submit = Submit(class level)

/StrutsHelloWorld/src/wintys/struts2/i18n/I18nAction_zh_CN.properties:
wintys.i18n.name = \u59D3\u540D(\u7C7B\u7EA7\u522B)
wintys.i18n.age = \u5E74\u9F84(\u7C7B\u7EA7\u522B)
wintys.i18n.submit = \u63D0\u4EA4(\u7C7B\u7EA7\u522B)

注意:包级别、类级别properties只有在jsp页面提交到action,正在显示的页面是.action时,才能被读取并显示。

5、其它
    a.Struts国际化由I18n拦截器实现(xwork-2.1.2.jar/com.opensymphony.xwork2.interceptor.I18nInterceptor)。

    b.在浏览器中设置不同的语言首选项即可看到国际化的效果。

6、详细代码
/StrutsHelloWorld/WebRoot/i18n/input.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>register</title>
    <meta http-equiv="pragma" content="no-cache">
  </head>
 
  <body>
      <s:actionerror/>
      
      <s:text name="wintys.i18n.title" />
      
    <s:form action="i18n" >
        <!--s:textfield name="name" label="姓名"/ -->
        <!-- s:textfield name="age" label="年龄" / -->
        <!-- s:submit name="submit" value=" 提交  " / -->
        <s:textfield name="name" key="wintys.i18n.name"></s:textfield><br/>
        <s:textfield name="age" key="wintys.i18n.age"></s:textfield><br/>
        <s:submit name="submit" key="wintys.i18n.submit"></s:submit>
    </s:form>
    
    <s:i18n name="messagefile">
        <s:text  name="wintys.i18n.desc"/><br/>
        <s:text name="wintys.i18n.addition">
            <s:param>Hello</s:param>
        </s:text>
    </s:i18n>
  </body>
</html>


/StrutsHelloWorld/WebRoot/i18n/output.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>    
    <title>My JSP 'output.jsp' starting page</title>
  </head>
 
  <body>
    姓名:<s:property value="name"/><br/>
    年龄:<s:property value="age"/><br/>
  </body>
</html>

struts.xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <!-- 定义全局错误信息资源文件message.properties -->
    <constant name="struts.custom.i18n.resources" value="message" />
    <package name="MyStruts" extends="struts-default">        
        <!-- 国际化 -->
        <action name="i18n" class="wintys.struts2.i18n.I18nAction">
            <result name="success">/i18n/output.jsp</result>
            <result name="input">/i18n/input.jsp</result>
        </action>
    </package>
</struts>


/StrutsHelloWorld/src/message_en_US.properties:
wintys.i18n.title=Register
wintys.i18n.name.invalid=NAME should not be empty.
wintys.i18n.age.conversion.error = age conversion error.
wintys.i18n.age.exceed.range = age exceed range: ${min} ~ ${max}

wintys.i18n.name = Name(global level)
wintys.i18n.age = Age(global level)
wintys.i18n.submit = Submit(global level)


/StrutsHelloWorld/src/message_zh_CN.properties:
wintys.i18n.title=\u6CE8\u518C
wintys.i18n.name.invalid =\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A
wintys.i18n.age.conversion.error =\u5E74\u9F84\u8F6C\u6362\u9519\u8BEF
wintys.i18n.age.exceed.range =\u5E74\u9F84\u8D85\u51FA\u8303\u56F4\: ${min} ~ ${max}

wintys.i18n.name = \u59D3\u540D(\u5168\u5C40)
wintys.i18n.age = \u5E74\u9F84(\u5168\u5C40)
wintys.i18n.submit =\u63D0\u4EA4(\u5168\u5C40)



[参考资料]:
    [1] 《浪曦视频之Struts2应用开发系列》
    [2] 【Java EE】struts2国际化 : http://www.cnitblog.com/intrl/archive/2009/04/18/56464.html
    [3] Struts2 的国际化 : http://hi.baidu.com/countryroadtao/blog/item/4ac77e2b6ec3c4305243c125.html

[附件]:
    源代码 : http://www.blogjava.net/Files/wintys/Struts_helloworld_i18n.zip
posted on 2009-08-10 18:13 天堂露珠 阅读(750) 评论(2)  编辑  收藏 所属分类: Struts

FeedBack:
# re: [原]Struts2-国际化 2009-08-28 18:46 心梦帆影
嗯,不错,把浪曦视频中的Struts2.0的内容运行在Struts2.1.6版本中.
继续学习,呵呵

有时间, 学一下Struts2.1.6的新特性!  回复  更多评论
  
# re: [原]Struts2-国际化 2009-08-29 16:59 天堂露珠
好的,多谢提醒。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: