编写:徐建祥(netpirate@gmail.com)
时间:2006-08-18 03:42
来自:http://www.anymobile.org
<术语>
国际化:internationalize,简称i18n,是指应用程序可以适应不同语言和地区的变化而变化的方案。
本地化:localization,检查l10n,是指应用程序适应某特定语言和地区的过程。
软件国际化是软件发展之必然,几乎所有的大众软件都支持多语言,最常见的就是英文软件的汉化版。
Java语言提供了基于unicode的国际化支持。通过Locale对象定义地区、语言、操作系统等信息,调用ResourceBundle的getBundle方法实现资源文件的数据绑定,轻松本地化不同的语言版本。
通过ResourceBundle 和 Locale 2个类的定义可以看出 java 读取资源的流程为:language, country, variant -n-> language, country -n-> language -n-> Locale.getDefault()。
ResourceBundle.getBundle(StringbaseName)
ResourceBundle.getBundle(StringbaseName,Localelocale)
Locale(Stringlanguage)
Locale(Stringlanguage,Stringcountry)
Locale(Stringlanguage,Stringcountry,Stringvariant)
ResourceBundle 储存了键-值对形式的本地特殊化对象,如String,分为2种:ListResourceBundle和PropertyResourceBundle。
前者通过.class程序实现,后者通过.properties配置文件实现本地化,样例如下:
1、ListResourceBundle Example
1.1 默认(测试环境为中文)资源类
/**
*$File:Rb.java$
*$Revision:1.0.0$
*$$Date:2006-8-182:12:11$
*/
package
org.anymobile.test;
import
java.util.ListResourceBundle;
/**
*
*@authorXuJianxiang
*/
public
class
Rb
extends
ListResourceBundle
{
staticfinalObject[][]contents={
{"CHG","修改"},
{"MSG","消息"},
{"BYE","再见"}
};
publicObject[][]getContents()
{
returncontents;
}
}
1.2 英文资源类
/**
*$File:Rb_en.java$
*$Revision:1.0.0$
*$Date:2006-8-182:14:37$
*/
package
org.anymobile.test;
import
java.util.ListResourceBundle;
/**
*
*@authorXuJianxiang
*/
public
class
Rb_en
extends
ListResourceBundle
{
staticfinalObject[][]contents={
{"CHG","change"},
{"MSG","message"},
{"BYE","bye"}
};
publicObject[][]getContents()
{
returncontents;
}
}
1.3测试类
/**
*$File:MyListResourceBundle.java$
*$Revision:1.0.0$
*$Date:2006-8-182:24:30$
*/
package
org.anymobile.test;
import
java.util.Locale;
import
java.util.MissingResourceException;
import
java.util.ResourceBundle;
/**
*Testjava.util.ListResourceBundle
*
*@authorXuJianxiang
*/
public
class
MyListResourceBundle
{
publicstaticvoidmain(String[]args)
{
StringbaseName="org.anymobile.test.Rb";
Stringkey="BYE";
try
{
ResourceBundleres=ResourceBundle.getBundle(baseName);
System.out.println(res.getString(key));
res=ResourceBundle.getBundle(baseName,Locale.ENGLISH);
System.out.println(res.getString(key));
}
catch(MissingResourceExceptionexp)
{
exp.printStackTrace();
}
}
}
运行结果:
bye
2、PropertyResourceBundle Example
2.1 英文配置文件({project}/classes/resources/rb_en.properties)
#rb_en.properties
CHG=change
MSG=message
BYE=bye
2.2 中文配置文件({project}/classes/resources/rb_zn_CN.properties)
#rb_zn_CN.properties
CHG=修改
MSG=消息
BYE=再见
2.3 测试类
/**
*$File:MyResourceBoundle.java$
*$Revision:1.0.0$
*$Date:2006-8-181:19:06$
*/
package
org.anymobile.test;
import
java.util.Locale;
import
java.util.MissingResourceException;
import
java.util.ResourceBundle;
/**
*Testjava.util.PropertyResourceBundle
*
*@authorXuJianxiang
*/
public
class
MyPropResourceBundle
{
publicstaticvoidmain(String[]args)
{
StringbaseName="resources.rb";
Stringkey="CHG";
try
{
//ResourceBundleres=ResourceBundle.getBundle(baseName,Locale
//.getDefault());
ResourceBundleres=ResourceBundle.getBundle(baseName,newLocale("zh","CN","WINDOWS"));
System.out.println(key+":"+res.getString(key));
res=ResourceBundle.getBundle(baseName,Locale.ENGLISH);
System.out.println(key+":"+res.getString(key));
}
catch(MissingResourceExceptionexp)
{
exp.printStackTrace();
}
}
}
运行结果:
CHG: change
另外,为了不致于在程序中产生乱码,可以通过jdk自带的native2ascii程序将.properties文件从本地编码转换成unicode编号格式的数据文件,为避免读取时因编码问题而出现乱码,可以先编写一个src.txt文件,然后执行指令:native2ascii src.txt dest.properties。转换后,如“中国”的unicode字符码为“/u4e2d/u56fd”。
如果需要将unicode恢复成原编码,可以执行指令:native2ascii -reverse dest.file src.file。
每次必须运行native2ascii方法比较繁琐,实际开发中,可以通过Apache Ant的native2Ascii任务进行批量转码。如:<native2ascii encoding="GBK" src="${src}" dest="${build}"/>
3、Spring 的消息国际化
org.springframework.context.ApplicationContext继承了org.springframework.context.MessgeResource接口,通过起getMessage()的各个版本读取文字消息的资源文件,从而实现消息国际化。
public interface MessageSource
{
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
}
参考资料:
Java 2 SDK Document
How to internationalize Java applications(Sun)http://java.sun.com/docs/books/tutorial/i18n/index.html
ISO Language Codehttp://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
ISO Country Codehttp://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html
本文介绍Java中的国际化(i18n)和本地化(l10n)概念,重点讲解如何使用ResourceBundle和Locale实现多语言支持,包括ListResourceBundle和PropertyResourceBundle的具体应用实例。

被折叠的 条评论
为什么被折叠?



