編寫:徐建祥([email protected])
時間: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(String baseName)
ResourceBundle.getBundle(String baseName, Locale locale)
Locale(String language)
Locale(String language, String country)
Locale(String language, String country, String variant)
ResourceBundle 儲存了鍵-值對形式的本地特殊化對象,如String,分為2種:ListResourceBundle和PropertyResourceBundle。
前者通過.class程式實作,後者通過.properties配置檔案實作本地化,樣例如下:
1、ListResourceBundle Example
1.1 預設(測試環境為中文)資源類
package org.anymobile.test;
import java.util.ListResourceBundle;
public class Rb extends ListResourceBundle
{
static final Object[][] contents = {
{ "CHG", "修改" },
{ "MSG", "消息" },
{ "BYE", "再見" }
};
public Object[][] getContents()
{
return contents;
}
}
1.2 英文資源類
package org.anymobile.test;
import java.util.ListResourceBundle;
public class Rb_en extends ListResourceBundle
{
static final Object[][] contents = {
{ "CHG", "change" },
{ "MSG", "message" },
{ "BYE", "bye" }
};
public Object[][] getContents()
{
return contents;
}
}
1.3 測試類
package org.anymobile.test;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class MyListResourceBundle
{
public static void main( String[] args )
{
String baseName = "org.anymobile.test.Rb";
String key = "BYE";
try
{
ResourceBundle res = ResourceBundle.getBundle( baseName );
System.out.println( res.getString( key ) );
res = ResourceBundle.getBundle( baseName, Locale.ENGLISH );
System.out.println( res.getString( key ) );
}
catch ( MissingResourceException exp )
{
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 測試類
package org.anymobile.test;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class MyPropResourceBundle
{
public static void main( String[] args )
{
String baseName = "resources.rb";
String key = "CHG";
try
{
// ResourceBundle res = ResourceBundle.getBundle( baseName, Locale
// .getDefault() );
ResourceBundle res = ResourceBundle.getBundle( baseName, new Locale("zh","CN","WINDOWS") );
System.out.println( key + ": " + res.getString( key ) );
res = ResourceBundle.getBundle( baseName, Locale.ENGLISH );
System.out.println( key + ": " + res.getString( key ) );
}
catch ( MissingResourceException exp )
{
exp.printStackTrace();
}
}
}
運作結果:
CHG: 改變
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 Code http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
ISO Country Code http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html