浏览 1810 次
锁定老帖子 主题:Java内置的国际化
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2014-01-03
Struts2的国际化也不是无本之木,它依赖于Java内置的国际化机制,只是在Java内置的国际化机制的基础上增加了跟Struts2其他组件的融合,使得其他组件也可以非常方便的使用国际化。 9.2.1 Java内置的国际化入门 1:准备国际化信息文件 Java内置的国际化,以java.util.ResourceBundle和java.util.Locale两个类为中心。其中, java.util.Locale负责选择合适的语言,而java.util.ResourceBundle负责根据注入的java.util.Locale对象来选择国际化信息的来源,返回国际化信息。 如果我们的软件支持中文和英文两种语言,而以中文作为默认的语言。则会出现三种语言,默认的语言(中文)、中文和英文,当然,其实只有两种语言中文和英文。但是,以中文为默认的语言是非常必要的。有时候,软件需要应对的语言不一定只有中文和英文;如果法国的朋友想要使用软件呢?由于不存在法文的信息,这时候只能返回默认的语言,那就是中文了。 在这种情况下准备国际化资源文件,一般准备三个文件,分别是默认语言、中文与英文的文件。 每个文件都以properties为扩展名,内容以key-value对的形式存在,其中key是如何引用这条信息,而value就是这条信息真正要显示的内容了。 综上所述,可以准备如下三个文件作为国际化信息的文件。 (1)默认语言文件:message.properties java代码: 查看复制到剪贴板打印 labela = labela in zh_CN labelb = labelb in zh_CN 注意:在这个文件中,本应该在“=”后面写上中文,但是,我们没有这样做,这是因为Java内置的国际化在处理中文的时候还需要一步特殊处理,这在后面有专门的章节处理,因此这里就没有使用中文了。 (2)中文语言文件:message_zh_CN.properties java代码: 查看复制到剪贴板打印 #labela = labela in zh_CN #labelb = labelb in zh_CN 注意:故意在两行之前都加了一个#,这在properties文件中代表注释的意思,也就是说这个message_zh_CN.properties实际上是空的。 (3)英文语言文件:message_en_US.properties java代码: 查看复制到剪贴板打印 labela = labela in en_US labelb = labelb in en_US 先不去考虑客户端怎么写,观察一下这三个文件的命名。它们拥有共通的前缀message,代表了它们是同一组国际化信息的不同语言;它们各自的后缀代表了自己的语言,其中没有后缀(message.properties)的文件,代表这是默认语言文件。 2:使用ResouceBundler和Locale选择多语言信息 将上面的三个文件拷贝到工程的src目录下备用。然后就可以在Java程序中引用这些多语言信息了。 在引用多语言信息的时候,要做三件事情: 引用哪种语言。 引用哪组多语言文件。 引用这种语言的这组文件里的哪条信息。 带着这三个问题,一起来看一下Java中的客户端: java代码: 查看复制到剪贴板打印 package cn.javass.i18n; import java.util.Locale; import java.util.ResourceBundle; public class Test { public static void main(String[] args) { //选择中文 Locale locale1 = Locale.SIMPLIFIED_CHINESE; //选择message这组文件 ResourceBundle bundle1 = ResourceBundle.getBundle("message",locale1); //选择其中的labela这一项 System.out.println("bundle1=="+bundle1.getString("labela")); Locale locale2 = Locale.US; ResourceBundle bundle2 = ResourceBundle.getBundle("message",locale2); System.out.println("bundle2=="+bundle2.getString("labela")); Locale locale3 = Locale.FRANCE; ResourceBundle bundle3 = ResourceBundle.getBundle("message",locale3); System.out.println("bundle3=="+bundle3.getString("labela")); } } Locale类里预置了许多语种,上面代码中引用的Locale.SIMPLIFIED_CHINESE对应zh_CN,Locale.US对应en_US,Locale.FRANCE对应fr_FR;也就确定了前面所说的文件名后缀。 ResouceBundle.getBundle方法传入的第一个参数就是要引用哪组文件,也就确定了前面所说的文件名前缀。 由前缀和后缀共同作用取得的ResourceBundle对象就代表了一个文件中的所有多语言信息,它的getString方法传入的参数就是前面所说的key,而且返回值就是实际需要的value。 运行测试一下,结果如下: java代码: 查看复制到剪贴板打印 bundle1==labela in zh_CN bundle2==labela in en_US bundle3==labela in zh_CN 9.2.2对中文的支持 在上一节中并没有在message.properties中写中文。现在,试着写一下中文,把“labela in zh_CN”改成“labela in 中文”,发现eclipse根本保存不了,eclipse会报错,这是因为properties文件只支持ascii码,而中文使用了Unicode,这该怎么办呢? 方法特别简单,找个工具把中文转换成ascii码就可以了,比如native2ascii的工具,它可以在jdk安装路径下的bin目录中找到。 使用native2ascii的基本步骤如下: 1、要先把message.proerties改个名字,比如为src_message.properties,因为message.properties这个文件要用来存储操作后的内容。 2、用文本编辑器来编辑src_message.properties,加入中文。 java代码: 查看复制到剪贴板打印 labela = labela in 中文 labelb = labelb in 中文 3、在cmd窗口中找到工程的src文件夹,运行如下命令。 java代码: 查看复制到剪贴板打印 native2ascii src_message.properties message.properties 然后在eclipse中刷新一下工程,会发现多出了message.properties,里面的内容为 java代码: 查看复制到剪贴板打印 labela = labela in \u4e2d\u6587 labelb = labelb in \u4e2d\u6587 这就是转换后的中文。 再次运行上一节的java客户端,我们可以发现,中文已经能正确显示了。 java代码: 查看复制到剪贴板打印 bundle1==labela in 中文 bundle2==labela in en_US bundle3==labela in 中文 提示:为了保证知识的紧凑,这里只是用了最原始的方法调用了native2ascii,在真正的项目中会有更好的方法去调用,比如写ant脚本、使用eclipse插件等等。 9.2.3向国际化信息传入参数 在实际项目中,只是在国际化信息文件中写死一个字符串还并不能满足要求。比如,用户可能会对已经确定的订单进行修改操作,但是这时候商品已经出库,所以订单就不允许修改了。 这种情况下,通常需要提示用户:“您的订单已处理,商品已出库,不允许修改”。可是,一个用户有可能有多张订单,这样一句简单的提示会让用户迷惑,到底哪张订单不允许修改啊? 如果写出更友好的提示,比如:“您的订单(201009290001)已处理,商品已出库,不允许修改”,这就明确了很多。 该怎么实现这种功能呢? 这时候,光用前面学的国际化知识就不够了。前面在国际化文件中写的文本都是死的,但是,订单号显然不能在文本中写死,因为任何一张订单都有可能不允许修改。对于这种情况,可以把订单编号作为参数传入国际化信息内。 要向国际化信息传入参数,需要考虑两方面事情: 在编写国际化信息时,如何给参数留出位置? 在客户端访问国际化信息时,如何把参数传入预定的位置? 在国际化信息中,是使用索引的方式来进行占位。可以将默认语言的国际化信息修改一下,为了简单,避免去转换中文,就用英文来示例了,示例如下: java代码: 查看复制到剪贴板打印 labela = your order({0}) is confirmed,can not be modified 在客户端中,需要使用MessageFormat类将参数合成进读出的国际化信息中,示例如下: java代码: 查看复制到剪贴板打印 public class Test { public static void main(String[] args) { //选择中文 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); } } 运行的结果为: java代码: 查看复制到剪贴板打印 your order(201009290001) is confirmed,can not be modified 有朋友可能会说,那怎么传入多个参数呢?比如把国际化的信息修改成如下示例: java代码: 查看复制到剪贴板打印 labela ={0},your order({1}) is confirmed,can not be modified 那么在程序里面,只要把传入的参数改成数组就可以了,示例如下: java代码: 查看复制到剪贴板打印 public class Test { public static void main(String[] args) { //选择中文 Locale locale1 = Locale.SIMPLIFIED_CHINESE; //选择message这组文件 ResourceBundle bundle1 = ResourceBundle.getBundle("message",locale1); //选择其中的labela这一项 String message = bundle1.getString("labela"); //将参数合成进读出的国际化信息 String[] params = new String[2]; params[0] = "Petter"; params[1] = "201009290001"; String info = MessageFormat.format(message, params); System.out.println(info); } } 运行的结果如下: java代码: 查看复制到剪贴板打印 Petter,your order(201009290001) is confirmed,can not be modified 9.2.4小结 本节中介绍的都是Java内置的国际化信息的使用,而Struts2的国际化,是在Java内置的国际化支持的基础上对其包装使用,因此,以上的特性在Struts2中都得到了体现,也就是说在这节中学到的知识,到Struts2中仍然有用。 私塾在线原创 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |