天天看點

【Java】I18N國際化

       i18n(其來源是英文單詞internationalization的首末字元i和n,18為中間的字元數)是“國際化”的簡稱。對程式來說,在不修改内部代碼的情況下,能根據不同語言及地區顯示相應的界面。

       這就要求,僅僅是頁面語言的翻譯是不夠的,即便在一個國家在不同地區都可能會存在不同習慣方言操作習慣等等(例如我們國家搜尋結果習慣左對齊,但是有的國家就習慣右對齊),這就導緻了“本地化”(L10n)機制的出現。

       國際化和本地化的出現,在語言、文化、書寫習慣、閱讀習慣、符合當地主題的全面配置,使得一個Web應用程式在運作時能夠根據用戶端請求所來自的國家和語言顯示不同的使用者界面。

【示例】

根據以上簡介和檢視的具體軟體的配置,了解一下i18n吧,是以小編檢視了一下QQ的i18n配置檔案,如下:

<?xml version="1.0" encoding="utf-8" ?>
<i18n>
	<!-- 預設的語言,以主程式的優?-->
	<locale id="2052" />
	<!-- 語言文字清單 -->
	<StringBundle>
		<configfile name="GFStringBundle.xml"/>		
		<configfile name="StringBundle.xml"/>
		<configfile name="UrlBundle.xml"/>
	</StringBundle>
	<!-- 地區資訊,目前隻需要一?-->
	<Location2>
		<configfile name="LocList.xml"/>
	</Location2>
	<LangList>
		<configfile name="LangList.xml"/>
	</LangList>
</i18n>
           

又檢視了一下要讀取的LangList.xml檔案,很壯觀,如下:

<?xml version="1.0" encoding="utf-8"?>
<Languages>
	<Language LCID="1078" Name="南非荷蘭語" Code="af"/>
	<Language LCID="1052" Name="阿爾巴尼亞語" Code="sq"/>
	<Language LCID="1025" Name="阿拉伯語" Code="ar"/>
	<Language LCID="1067" Name="亞美尼亞語" Code="hy"/>
	<Language LCID="2092" Name="阿塞拜疆語" Code="az"/>
	<Language LCID="1059" Name="白俄羅斯語" Code="be"/>
	<Language LCID="5146" Name="波斯尼亞語" Code="bs-ba"/>
	<Language LCID="1026" Name="保加利亞語" Code="bg"/>
	<Language LCID="1109" Name="緬甸語" Code="my"/>
	<Language LCID="3076" Name="中文(繁體)" Code="zh-hk"/>
	<Language LCID="1027" Name="加泰羅尼亞語" Code="ca"/>
	<Language LCID="1050" Name="克羅地亞語" Code="hr"/>
	<Language LCID="1029" Name="捷克語" Code="cs"/>
	<Language LCID="1030" Name="丹麥語" Code="da"/>
	<Language LCID="1043" Name="荷蘭語" Code="nl"/>
	<Language LCID="1033" Name="英語" Code="en-us"/>
	<Language LCID="1061" Name="愛沙尼亞語" Code="et"/>
	<Language LCID="1065" Name="波斯語" Code="fa"/>
	<Language LCID="1035" Name="芬蘭語" Code="fi"/>
	<Language LCID="1036" Name="法語" Code="fr"/>
	<Language LCID="2108" Name="蓋爾語" Code="gd"/>
	<Language LCID="1031" Name="德語" Code="de"/>
	<Language LCID="1032" Name="希臘語" Code="el"/>
	<Language LCID="1095" Name="古吉拉特語" Code="gu"/>
	<Language LCID="1037" Name="希伯來語" Code="he"/>
	<Language LCID="1081" Name="印地語" Code="hi"/>
	<Language LCID="1038" Name="匈牙利語" Code="hu"/>
	<Language LCID="1039" Name="冰島語" Code="is"/>
	<Language LCID="1057" Name="印度尼西亞語" Code="id"/>
	<Language LCID="1040" Name="意大利語" Code="it"/>
	<Language LCID="1041" Name="日語" Code="ja"/>
	<Language LCID="1107" Name="高棉語" Code="km"/>
	<Language LCID="1042" Name="北韓語" Code="ko"/>
	<Language LCID="1108" Name="寮國語" Code="lo"/>
	<Language LCID="1062" Name="拉脫維亞語" Code="lv"/>
	<Language LCID="1063" Name="立陶宛語" Code="lt"/>
	<Language LCID="1071" Name="馬其頓語" Code="mk"/>
	<Language LCID="1086" Name="馬來西亞語" Code="ms"/>
	<Language LCID="2052" Name="中文(簡體)" Code="zh-cn"/>
	<Language LCID="1104" Name="蒙古語" Code="mn"/>
	<Language LCID="1044" Name="挪威語" Code="no"/>
	<Language LCID="1045" Name="波蘭語" Code="pl"/>
	<Language LCID="2070" Name="葡萄牙語" Code="pt"/>
	<Language LCID="1094" Name="旁遮普語" Code="pa"/>
	<Language LCID="1048" Name="羅馬尼亞語" Code="ro"/>
	<Language LCID="1049" Name="俄語" Code="ru"/>
	<Language LCID="3098" Name="塞爾維亞語" Code="sr"/>
	<Language LCID="1113" Name="信德語" Code="sd"/>
	<Language LCID="1051" Name="斯洛伐克語" Code="sk"/>
	<Language LCID="1060" Name="斯洛文尼亞語" Code="sl"/>
	<Language LCID="1143" Name="索馬裡語" Code="so"/>
	<Language LCID="1034" Name="西班牙語" Code="es"/>
	<Language LCID="1089" Name="斯瓦西裡語" Code="sw"/>
	<Language LCID="1053" Name="瑞典語" Code="sv"/>
	<Language LCID="1097" Name="泰米爾語" Code="ta"/>
	<Language LCID="1092" Name="鞑靼語" Code="tt"/>
	<Language LCID="1054" Name="泰語" Code="th"/>
	<Language LCID="1055" Name="土耳其語" Code="tr"/>
	<Language LCID="1058" Name="烏克蘭語" Code="uk"/>
	<Language LCID="1056" Name="烏爾都語" Code="ur"/>
	<Language LCID="1066" Name="越南語" Code="vi"/>
	<Language LCID="1106" Name="威爾士語" Code="cy-gb"/>
	<Language LCID="1085" Name="意第緒語" Code="yi"/>
	<Language LCID="1130" Name="約魯巴語" Code="yo"/>
</Languages>
           

【實踐】

1.locale方法

     Java.Util中有一個locale方法,該方法的其中一個構造方法為:

    Locale(Stringlanguage,String country):根據語言和國家構造一個語言環境。每個國家都有一個locale資訊,通過對象可以取得locale資訊,locale資訊來源于作業系統。如下:

package com.bjpowernode.i18n;

import java.util.Locale;

public class I18nSample {

	public static void main(String[] args) {

		Locale defaultLocale = Locale.getDefault();
		System.out.println("country=" + defaultLocale.getCountry());
		System.out.println("language=" + defaultLocale.getLanguage());

	}
}
           

運作結果為:

country=CN

language=zh

      但是在我們下面的實踐中,為了友善我們就直接進行設定了。

2.ResourceBundle資源包

       我們需要将寫死文本轉移到外部的資源檔案,對資源檔案的命名必須使用一定的規則,一般是以“統一字元+locale資訊”命名,如MessagesBundle_zh_CN.properties,MessagesBundle_en_US.properties。準備資源包的過程,就是把對應不同語言的使用者所涉及的文本和圖檔儲存在多個文本檔案中,用戶端根據不同的環境需要進行更換。這些檔案被稱為“屬性檔案”,所有屬性檔案合在一起被稱為資源包(ResourceBundle)。

        因為資源檔案必須是Latin-1後者Unicode編碼的字元,是以實踐過程中,準備英文好說,準備中文的話,需要使用相應的Unicode編碼,使用jdk自帶的native2ascii.exe,将中文資源檔案進行轉換,如下:

【Java】I18N國際化
【Java】I18N國際化

也可以直接在資源檔案中添加,會自動轉換成Unicode編碼,如下:

【Java】I18N國際化

結果如下:

【Java】I18N國際化

Demo中我們中文和英文準備的都是:k1=你好/hello,k2=再見/goodbye。

【實踐代碼】

package com.bjpowernode.i18n;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

public class I18nSample {

	public static void main(String[] args) {
		// 為了實驗,就不每次都修改作業系統的語言了,直接設定locale資訊
		// Locale currentLocale = new Locale("zh", "CN");
		Locale currentLocale = new Locale("en", "US");

		System.out.println("country=" + currentLocale.getCountry());
		System.out.println("language=" + currentLocale.getLanguage());

		// 根據locale資訊尋找相應的資源包中的配置
		ResourceBundle rb = ResourceBundle.getBundle(
				"com.bjpowernode.resources.MessagesBundle", currentLocale);
		System.out.println(rb.getString("k1"));
		System.out.println(rb.getString("k2"));
		// 在配置檔案中用占位符來加入自定義設定,如登陸時顯示:你好,***
		MessageFormat mf = new MessageFormat(rb.getString("k1"));
		System.out.println(mf.format(new Object[] { "張三" }));
	}
}
           

運作結果為:

country=US

language=en

hello,{0}

good bye

hello,張三