最愛Java

          書山有路勤為徑,學海無涯苦作舟

          2010年11月11日

              Java程序的國際化主要通過三個類完成:

              java.util.ResourceBundle:用于加載一個資源包。

              java.util.Locale:對應一個特定的國家/區域、語言環境。

              java.text.MessageFormat:用于消息格式化。

              而資源文件的命名方式主要有三種:baseName_language_country.properties、baseName_language.properties和baseName.properties。

              以下的程序可以得到Java所支持的語言和國家:

          public class LocalList {
              
          public static void main(String[] args){
                  Locale[] localeList 
          = Locale.getAvailableLocales();
                  
          for (int i=0;i<localeList.length;i++){
                      System.out.println(localeList[i].getdisplayCountry() 
          + "=" + localeList[i].getCountry() + " " + localeList[i].getDisplayLanguage() + "=" + localeList[i].getLanguage());
                  }

              }

          }

              使用國際化的代碼如: 

          public class Hello{
              
          public static void main(String[] args){
                  Locale myLocale 
          = Locale.getDefault();
                  ResourceBundle bundle 
          = ResourceBundle.getBundle("mess",myLocale);
                  System.out.println(bundler.getString(
          "hello"));
              }

          }

              如果在資源文件中,存在例如msg = Hello,{0}!Today is {1}.這樣需要程序動態插入參數的文本,則需要使用MessageFormat類的format()方法。

              除了使用資源文件,我們也可以使用類文件來代替資源文件。使用Java文件代替資源文件的Java文件必須滿足:1。類名必須是baseName_language_country,這與屬性文件的命名相似。2。該類必須繼承ListResourceBundle,并重寫getContents方法,該方法返回Object數組。該數組的每一個項都是key-value對。

          public class MyResource_zh_CN extends ListResourceBundle {
              
          //定義資源
              private final Object myData[][] = {
                  
          {"msg","類文件消息:{0},您好!今天是{1}"}
              }
          ;
              @Override
              
          public Object[][] getContents(){
                  
          return myData;
              }

          }


              對于簡體中文的Locale,ResourceBundler搜索資源的順序是:

              baseName_zh_CN.class;baseName_zh_CH.properties;baseName_zh.class;baseName_zh.properties;baseName.class;baseName.properties

           

              Struts2訪問國際化消息,主要有3種方式:1)JSP頁面輸出國際化消息,可以使用Struts2的<s:text.../>標簽,該標簽可以指定一個name屬性,該屬性就是資源文件中的key。2)在Action中,可以使用ActionSupport類的getText方法,該方法可以接受一個name參數,指定了國際化資源文件中的key。3)表單元素的Label,可以為表單標簽指定一個key屬性,這個key指定了國際化資源文件的key。

               對于帶占位符的國際化消息,在Action中,則需要使用getText(String key, String[] args)來處理,其中args就是參數列表;而在頁面中,則需要為<s:text.../>標簽指定<s:param.../>子標簽。如:

          <s:text name="welcomeMsg">
              
          <s:param><s:property value="username"></s:param>
          </s:text>


             在Struts2中,還有一種更加簡單的表達方式。我們可以在資源文件中寫例如這樣的表達式:failTip=${username},對不起,您不能登錄!,通過使用表達式,可以從ValueStack中取出username屬性值,自動填充到消息資源中。這在Action中很常用。

              對于一個大型應用而言,國際化資源文件的管理也是一個非常浩大的工程。為了能更好的分而治之,Struts2允許針對不同的模塊、不同Action來組織國家化資源文件。

               為Strut2應用指定包范圍資源文件的方法是:在包的跟路徑下建立多個文件名為package_language_country.properties的文件,一旦建立了這個系列的國際化資源文件,應用中處于該包下的所有Action都可以訪問該資源文件。

              例如一個Action為codes\packageScope\src\lee\action\LoginAction.java,那么我們可以提供package_zh_CN.properties和package_en_US.properties兩個文件放在codes\packageScope\src\lee目錄下,那么這兩個文件就能被lee包及lee包下所有子包內的Action所能訪問。

              同時,我們也可以為LoginAction單獨指定一份國際化資源文件。即在codes\packageScope\src\lee\action目錄下,分別建立LoginAction_zh_CN.properties和LoginAction_en_US.properties兩個文件。

              有時候,處于某種特殊的原因,我們需要臨時指定資源文件,那么就需要使用<s:i18n.../>來充當<s:text.../>標簽的父標簽了。如:

          <s:i18n name="tmp">
              
          <s:text name="loginPage"/>
          </s:i18n>

          <s:i18n name="tmp">
              
          <s:form action="login">
                  
          <s:textfield name="username" key="user"/>
                  
          <s:textfield name="password" key="pass"/>
                  
          <s:submit key="login"/>
              
          </s:form>
          </s:i18n>


              加載資源文件的順序:

          1.     優先加載系統中保存在ChildAction的類文件相同位置,且baseName為ChildAction的系列資源文件。
          2.     如果在1)中找不到key對應的消息,且ChildAction有父類ParentAction,則加載系統中保存在ParentAction的類文件相同位置,且baseName為ParentAction的系列資源文件。
          3.     如果2)中找不到key對應的消息,且ChildAction有實現接口IChildAction,則加載系統中保存在IChildAction的類文件相同位置,且baseName為IChildAction的系列資源文件。
          4.     如果3)中找不到key對應的消息,且ChildAction有實現接口ModelDriven(即使用模型驅動模式),則對于getModel()方法返回的model對象,重新執行1)步操作。
          5.     如果在4)中找不到key對應的消息,則查找當前包下baseName為package的系列資源文件。
          6.     如果在5)中找不到key對應的消息,則沿著當前包上溯,直到最頂層包來查找baseName為package的系列資源文件。
          7.     如果在6)中找不到key對應的消息,則查找struts.custom.i18n.resources常量指定baseName的系列資源文件。
          8.     如果經過上面步驟一直找不到key對應的消息,將直接輸出該key的字符串值

                對于在JSP中訪問國際化消息,則簡單很多,可以分為兩種形式:

                1)對于使用<s:i18n.../>標簽作為父標簽的<s:text.../>標簽,將直接從<s:i18n.../>標簽指定的國際化資源文件中加載指定key對應的消息,如果沒有,則讀取struts.custom.i18n.resources常量指定baseName的系列文件。如果還沒有,直接輸出key。

               2)對于沒有使用<s:i18n.../>標簽作為父標簽的<s:text.../>標簽,則直接讀取struts.custom.i18n.resources常量指定baseName的系列文件。如果沒有,直接輸出key。

              Struts2中, 我們可以通過ActionContext.getContext().setLocale(Locale arg)設置用戶的默認語言。同時在Struts2 的defaultStack攔截棧中,i18n攔截器也能設置默認語言。i18n在執行Action方法前,會自動查找一個名為request_locale的參數。如果這個參數存在,則攔截器會將其轉換成Locale對象,并設為默認的Locale。同時,這個Locale對象會保存在Session的名為WW_TRANS_I18N_LOCALE的屬性中。一旦用戶的Session中有WW_TRANS_I18N_LOCALE屬性,則屬性指定的Locale將會作為瀏覽器的默認Locale。因此,用戶也可利用此功能來開發自行選擇語言的功能。

          posted @ 2010-11-11 22:16 Brian 閱讀(328) | 評論 (0)編輯 收藏

          公告


          導航

          <2010年11月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          統計

          常用鏈接

          留言簿(4)

          隨筆分類

          隨筆檔案

          收藏夾

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 彰化市| 虎林市| 县级市| 定襄县| 博乐市| 东宁县| 枝江市| 乐陵市| 义马市| 临颍县| 武义县| 宁武县| 镶黄旗| 明水县| 克拉玛依市| 滦南县| 德江县| 铜陵市| 阜新市| 镇原县| 新郑市| 隆化县| 阳东县| 沭阳县| 读书| 新密市| 竹北市| 湖口县| 噶尔县| 元氏县| 星子县| 永福县| 曲松县| 灵丘县| 阳城县| 北辰区| 手机| 宾川县| 广元市| 英德市| 太和县|