`
反求诸己
  • 浏览: 534183 次
  • 性别: Icon_minigender_1
  • 来自: 湖南娄底
社区版块
存档分类
最新评论

研磨Struts2 之 第十三章 国际化

 
阅读更多
视频配套PPT,视频地址【 研磨Struts2视频课程
国际化(Internationalization),通俗点讲就是让软件 实现对多种语言的支持,可以通过简单的设置让软件支持的语言从一种切换到另一种。
当然,最直观的就是界面显示了,比如一个实现了国际化的软件,可以很容易的从英文界面切换成中文界面。在日常工作中也常见到国际化的软件,比如Eclipse就是多语言的,只要安装 了相应的语言包,在启动的时候指定语言参数就可以实现软件界面的快速转换。
在设计多语言实现的时候,要注意两点:
不能给软件开发带来过多的额外负担。
在改变语言或者添加一种语言的时候,不能修改已经写好的软件。
Struts2作为一款成熟的web 框架,自然也支持国际化,使用Struts2的时候,只要把对应的资源文件放在指定的地方,不用修改程序的主体,就可以对应新的语言要求。
Java 内 置的国际化,以java.util.ResourceBundle和java.util.Locale两个类为中心。其中, java.util.Locale负责选择合适的语言,而java.util.ResourceBundle负责根据注入的 java.util.Locale对象来选择国际化信息的来源,返回国际化信息。
准备三个文件,分别是默认语言、中文与英文的文件。都以properties为扩展名,内容以key-value对的形式存在,其中key是如何引用这条信息,而value就是这条信息真正要显示的内容了。可以准备
如下三个文件作为国际化信息的文件。
(1)默认语言文件:message.properties
labela = labela
labelb = labelb
(2)中文语言文件:message_zh_CN.properties
labela = labela in zh_CN
labelb = labelb in zh_CN
(3)英文语言文件:message_en_US.properties
labela = labela in en_US
labelb = labelb in en_US
在引用多语言信息的时候,要考虑三件事情:
引用哪种语言。
引用哪组多语言文件。
引用这种语言的这组文件里的哪条信息。
 
示例代码:
//选择中文
Locale locale1 = Locale.SIMPLIFIED_CHINESE;
//选择message这组文件
ResourceBundle bundle1 = ResourceBundle.getBundle("message",locale1);
//选择其中的labela这一项
System.out.println("bundle1=="+bundle1.getString("labela"));
ative2ascii  
我们已经装了eclipse插件,所以不需要手动转换。
转换前:
labela = labela in 中文
labelb = labelb in 中文
转换后:
labela = labela in \u4e2d\u6587
labelb = labelb in \u4e2d\u6587
在实际项目中,只是在国际化信息文件中写死一个字符串还并不能满足要求。比如,用户可能会对已经确定的订单进行修改操作,但是这时候商品已经出库,所以订单就不允许修改了。
 
使用索引的方式来进行占位  
labela = your order( {0} ) is confirmed,can not be modified
客户端:

java代码:
//选择中文
Locale locale1 = Locale.SIMPLIFIED_CHINESE;
//选择message这组文件
ResourceBundle bundle1 = ResourceBundle.getBundle("message",locale1);
//选择其中的labela这一项
String message = bundle1.getString("labela");
//将参数合成进读出的国际化信息
String info = MessageFormat.format(message, "201009290001");
System.out.println(info);
准备国际化信息资源文件  ,与之前一样,不再赘述。
 
设置  Struts2  引用国际化信息资源文件  
只需要在struts.xml中设置一个常量:

java代码:
<constant name="struts.custom.i18n.resources" value="message"/>
其中的值message,就是这组文件名中共同的前缀。
在jsp中,可以直接选用Struts2的text标签来访问国际化信息,其中text标签的name属性就是要引用哪个key。示例如下:
<s:text name="labela"/>
只需要在struts.xml中设置一个常量:  

java代码:
<constant name="struts.locale" value="zh_CN"/>
全局级资源文件只需要在struts.xml中或者struts.properties文件中设置常量值struts.custom.i18n.resources即可。
仍以前面在struts.xml中的设置为例,示例如下:

java代码:
<constant name="struts.custom.i18n.resources" value="message"/>
这里设置的message就是一组国际化资源文件名的前缀。如果有多组国际化资源文件,则以逗号分隔。如“message,dictionary”,就表示还另有一套以dictionary为前缀名的国际化资源文件,这些文件都放在classpath的根目录上。
包级资源文件指的是,在当前访问的Action的同包下,声明一组package.properties,可能包括package.properties、package_zh_CN.properties、package_en_US.properteis等等。
类 级资源文件比较复杂,这里先做一个简单的示例。可以在当前访问的Action类的同包下,声明一组以该Action类名为前缀的国际化资源文件,可能包括 Action类名.properties、Action类名_en_US.properties、Action类名_zh_CN.properties等 等。
比如访问的Action是cn.javass.i18n.I18NAction,那么,要设置的包级资源文件,就必须放在cn.javass.i18n这个包下,比如来建立一个I18NAction_zh_CN.properties文件。
类 级资源文件比较复杂,这里先做一个简单的示例。可以在当前访问的Action类的同包下,声明一组以该Action类名为前缀的国际化资源文件,可能包括 Action类名.properties、Action类名_en_US.properties、Action类名_zh_CN.properties等 等。
多种类级资源文件及其覆盖顺序
类级资源文件最为复杂,并不仅是一种,而是分为四种
ActionClass:资源文件名称的前缀必须与Action类名一致,在上面的示例中使用的就是这种。
MyInterface: 资源文件名称的前缀必须与Action实现的某一个接口名称一致,这个实现关系也并不一定是直接的实现关系,也有可能是当前类实现的接口的父接口,也有可 能是当前类的父类实现的接口。nMySuperClass:资源文件名称的前缀必须与Action的父类名一致,这个实现关系也并不一定是直接的继承关 系,也可能是当前类的父类。
如果动作类实现了ModelDriven接口,那么也会查找getModel方法返回类型的资源文件。
如果多种资源文件同时出现,将遵照上述类型出现的顺序进行覆盖,即ActionClass最优先,它会覆盖其他所有的资源文件,最常用的也是ActionClass这种方式。
资源文件很多,它们的覆盖顺序为:类级>包级>全局级。
(1)      <s:text>  访问国际化信息
1  :使用带参数的国际化信息
可以用参数把一些可变值传给国际化信息,在<s:text>标签访问国际化信息的时候,只需要配合上<s:param>子标签即可传入参数,示例如下:

java代码:
<s:text name="labelb">
<s:param>ok</s:param>
</s:text>
2  :指定国际化信息来源
可以通过<s:i18n>标签来为<s:text>标签指定国际化信息来源。如果<s:text>标签作为<s:i18n>标签的子标签出现,则会使用<s:i18n>指定的国际化信息来源。

java代码:
<s:i18n name="message">
<s:text name="labela"/>
</s:i18n>
解释一下如何引用国际化信息资源,仍然分为三种情况讨论:
全局级国际化信息资源:直接用文件前缀名即可—message。
包级国际化信息资源:用这个包的全限定名—cn.javass.i18n。
类级国际化信息资源:用这个类的全限定名—cn.javass. i18n.I18NAction。
(2)    用表单标签访问国际化信息
采用<s:form>的默认主题(xhtml)建立了一个一行一列的表单,其中,<s:textfield>标签的label属性用于在文本框前生成这个文本框的说明,label属性就是简单的把它的值“labela”放在了文本框前。
现在只需要做个小小的改动,就可以访问国际化的信息了,简单的把label属性改为key属性,就可以访问国际化信息来显示文本框前的说明信息了,示例如下:

java代码:
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:form>
<s:textfield name="name1" key="labela"/>
</s:form>
(3)      Action  中访问国际化信息
如果我们自己写的Action类继承自ActionSupport,就可以直接使用ActionSupport的一系列getText方法来访问国际化信息。这些方法声明于ActionSupport类实现的TextProvider接口。
分为两种情况讨论:
访问没有参数的国际化信息。
直接调用最简单的getText(String aTextName)即可,传入国际化信息的key,这个在前面讲ActionSupport的时候,就示例过这种情况。
访问有参数的国际化信息。
调 用可以设置参数的getText(String aTextName,String defaultValue,String… args),其中,第一个参数为国际化信息的key,第二个参数为找不到此key时返回的默认值,第三个String[]参数传入需要传给国际化信息的参 数。
(1)    Struts2  的常量设置
在struts.xml中加上struts.locale这个常量,值为需要使用的语言,示例如下:
<constant name="struts.locale" value="zh_CN"/>
(2)     浏览器设置
单击【外观】中的【语言】,得到浏览器的语言对话框。
点击添加按钮,在弹出的语言列表里面,选择“英语(美国)[en-US]”这个选项。
选择优先的语言信息。
(3)    由用户选择语言
Struts2提供了最灵活的、也是级别最高的方式,那就是由用户选择语言。用户只要在提交请求的时候加上request_locale这个参数,并提供对应的值就可以自由选择语言了。
这得力于Struts2的i18n内建拦截器,defaultStack拦截器栈引用了i18n拦截器,因此,能很方便的由用户来选择语言。
i18n 拦截器在Action运行之前会检查请求中是否包含了一个叫做“request_locale”的参数,如果存在此参数,则会用它的值建立一个 Locale对象,并用这个Locale对象去覆盖Struts2的常量设置和浏览器的语言设置。除此之外,i18n拦截器还会把这个Locale对象放 到名为WW_TRANS_I18N_LOCALE的Session属性中去,而这个属性也会覆盖Struts2的常量设置和浏览器的语言设置。因此,只需 要传入一次request_locale参数,session就会记住用户的选择,整个网站就会都变成用户选择的语言了。
(4)    三种方式的覆盖关系
对于这三种指定语言种类的方式,其优先级为:用户指定参数 > struts.xml中配置常量 > 浏览器设置
而且,用户参数指定的方式,只需要设置一次就可以了,在整个session生命周期内,都不用再次设置。
 
视频配套PPT,视频地址【 研磨Struts2视频课程
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics