Java程序的國(guó)際化主要通過(guò)三個(gè)類完成:
java.util.ResourceBundle:用于加載一個(gè)資源包。
java.util.Locale:對(duì)應(yīng)一個(gè)特定的國(guó)家/區(qū)域、語(yǔ)言環(huán)境。
java.text.MessageFormat:用于消息格式化。
而資源文件的命名方式主要有三種:baseName_language_country.properties、baseName_language.properties和baseName.properties。
以下的程序可以得到Java所支持的語(yǔ)言和國(guó)家:








使用國(guó)際化的代碼如:







如果在資源文件中,存在例如msg = Hello,{0}!Today is {1}.這樣需要程序動(dòng)態(tài)插入?yún)?shù)的文本,則需要使用MessageFormat類的format()方法。
除了使用資源文件,我們也可以使用類文件來(lái)代替資源文件。使用Java文件代替資源文件的Java文件必須滿足:1。類名必須是baseName_language_country,這與屬性文件的命名相似。2。該類必須繼承ListResourceBundle,并重寫getContents方法,該方法返回Object數(shù)組。該數(shù)組的每一個(gè)項(xiàng)都是key-value對(duì)。










對(duì)于簡(jiǎn)體中文的Locale,ResourceBundler搜索資源的順序是:
baseName_zh_CN.class;baseName_zh_CH.properties;baseName_zh.class;baseName_zh.properties;baseName.class;baseName.properties
Struts2訪問(wèn)國(guó)際化消息,主要有3種方式:1)JSP頁(yè)面輸出國(guó)際化消息,可以使用Struts2的<s:text.../>標(biāo)簽,該標(biāo)簽可以指定一個(gè)name屬性,該屬性就是資源文件中的key。2)在Action中,可以使用ActionSupport類的getText方法,該方法可以接受一個(gè)name參數(shù),指定了國(guó)際化資源文件中的key。3)表單元素的Label,可以為表單標(biāo)簽指定一個(gè)key屬性,這個(gè)key指定了國(guó)際化資源文件的key。
對(duì)于帶占位符的國(guó)際化消息,在Action中,則需要使用getText(String key, String[] args)來(lái)處理,其中args就是參數(shù)列表;而在頁(yè)面中,則需要為<s:text.../>標(biāo)簽指定<s:param.../>子標(biāo)簽。如:



在Struts2中,還有一種更加簡(jiǎn)單的表達(dá)方式。我們可以在資源文件中寫例如這樣的表達(dá)式:failTip=${username},對(duì)不起,您不能登錄!,通過(guò)使用表達(dá)式,可以從ValueStack中取出username屬性值,自動(dòng)填充到消息資源中。這在Action中很常用。
對(duì)于一個(gè)大型應(yīng)用而言,國(guó)際化資源文件的管理也是一個(gè)非常浩大的工程。為了能更好的分而治之,Struts2允許針對(duì)不同的模塊、不同Action來(lái)組織國(guó)家化資源文件。
為Strut2應(yīng)用指定包范圍資源文件的方法是:在包的跟路徑下建立多個(gè)文件名為package_language_country.properties的文件,一旦建立了這個(gè)系列的國(guó)際化資源文件,應(yīng)用中處于該包下的所有Action都可以訪問(wèn)該資源文件。
例如一個(gè)Action為codes\packageScope\src\lee\action\LoginAction.java,那么我們可以提供package_zh_CN.properties和package_en_US.properties兩個(gè)文件放在codes\packageScope\src\lee目錄下,那么這兩個(gè)文件就能被lee包及l(fā)ee包下所有子包內(nèi)的Action所能訪問(wèn)。
同時(shí),我們也可以為L(zhǎng)oginAction單獨(dú)指定一份國(guó)際化資源文件。即在codes\packageScope\src\lee\action目錄下,分別建立LoginAction_zh_CN.properties和LoginAction_en_US.properties兩個(gè)文件。
有時(shí)候,處于某種特殊的原因,我們需要臨時(shí)指定資源文件,那么就需要使用<s:i18n.../>來(lái)充當(dāng)<s:text.../>標(biāo)簽的父標(biāo)簽了。如:














加載資源文件的順序:
- 優(yōu)先加載系統(tǒng)中保存在ChildAction的類文件相同位置,且baseName為ChildAction的系列資源文件。
- 如果在1)中找不到key對(duì)應(yīng)的消息,且ChildAction有父類ParentAction,則加載系統(tǒng)中保存在ParentAction的類文件相同位置,且baseName為ParentAction的系列資源文件。
- 如果2)中找不到key對(duì)應(yīng)的消息,且ChildAction有實(shí)現(xiàn)接口IChildAction,則加載系統(tǒng)中保存在IChildAction的類文件相同位置,且baseName為IChildAction的系列資源文件。
- 如果3)中找不到key對(duì)應(yīng)的消息,且ChildAction有實(shí)現(xiàn)接口ModelDriven(即使用模型驅(qū)動(dòng)模式),則對(duì)于getModel()方法返回的model對(duì)象,重新執(zhí)行1)步操作。
- 如果在4)中找不到key對(duì)應(yīng)的消息,則查找當(dāng)前包下baseName為package的系列資源文件。
- 如果在5)中找不到key對(duì)應(yīng)的消息,則沿著當(dāng)前包上溯,直到最頂層包來(lái)查找baseName為package的系列資源文件。
- 如果在6)中找不到key對(duì)應(yīng)的消息,則查找struts.custom.i18n.resources常量指定baseName的系列資源文件。
- 如果經(jīng)過(guò)上面步驟一直找不到key對(duì)應(yīng)的消息,將直接輸出該key的字符串值
對(duì)于在JSP中訪問(wèn)國(guó)際化消息,則簡(jiǎn)單很多,可以分為兩種形式:
1)對(duì)于使用<s:i18n.../>標(biāo)簽作為父標(biāo)簽的<s:text.../>標(biāo)簽,將直接從<s:i18n.../>標(biāo)簽指定的國(guó)際化資源文件中加載指定key對(duì)應(yīng)的消息,如果沒(méi)有,則讀取struts.custom.i18n.resources常量指定baseName的系列文件。如果還沒(méi)有,直接輸出key。
2)對(duì)于沒(méi)有使用<s:i18n.../>標(biāo)簽作為父標(biāo)簽的<s:text.../>標(biāo)簽,則直接讀取struts.custom.i18n.resources常量指定baseName的系列文件。如果沒(méi)有,直接輸出key。
Struts2中, 我們可以通過(guò)ActionContext.getContext().setLocale(Locale arg)設(shè)置用戶的默認(rèn)語(yǔ)言。同時(shí)在Struts2 的defaultStack攔截棧中,i18n攔截器也能設(shè)置默認(rèn)語(yǔ)言。i18n在執(zhí)行Action方法前,會(huì)自動(dòng)查找一個(gè)名為request_locale的參數(shù)。如果這個(gè)參數(shù)存在,則攔截器會(huì)將其轉(zhuǎn)換成Locale對(duì)象,并設(shè)為默認(rèn)的Locale。同時(shí),這個(gè)Locale對(duì)象會(huì)保存在Session的名為WW_TRANS_I18N_LOCALE的屬性中。一旦用戶的Session中有WW_TRANS_I18N_LOCALE屬性,則屬性指定的Locale將會(huì)作為瀏覽器的默認(rèn)Locale。因此,用戶也可利用此功能來(lái)開(kāi)發(fā)自行選擇語(yǔ)言的功能。