<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    javaGrowing

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      92 隨筆 :: 33 文章 :: 49 評(píng)論 :: 0 Trackbacks

    用Java解決國(guó)際化問(wèn)題


    首都經(jīng)貿(mào)大學(xué)信息學(xué)院 尹海琴
    01-7-18 上午 09:11:22


    如果應(yīng)用系統(tǒng)是面向多種語(yǔ)言的,編程時(shí)就不得不設(shè)法解決國(guó)際化問(wèn)題,包括操作界面的風(fēng)格問(wèn)題、提示和幫助語(yǔ)言的版本問(wèn)題、界面定制個(gè)性化問(wèn)題等。
    由于Java語(yǔ)言具有平臺(tái)無(wú)關(guān)、可移植性好等優(yōu)點(diǎn),并且提供了強(qiáng)大的類庫(kù),所以Java語(yǔ)言可以輔助我們解決上述問(wèn)題。Java語(yǔ)言本身采用雙字節(jié)字符編 碼,采用大漢字字符集,這就為解決國(guó)際化問(wèn)題提供了很多方便。從設(shè)計(jì)角度來(lái)說(shuō),只要把程序中與語(yǔ)言和文化有關(guān)的部分分離出來(lái),加上特殊處理,就可以部分解 決國(guó)際化問(wèn)題。在界面風(fēng)格的定制方面,我們把可以參數(shù)化的元素,如字體、顏色等,存儲(chǔ)在數(shù)據(jù)庫(kù)里,以便為用戶提供友好的界面;如果某些部分包含無(wú)法參數(shù)化 的元素,那么我們可能不得不分別設(shè)計(jì),通過(guò)有針對(duì)性的編碼來(lái)解決具體問(wèn)題。
    Java類包
    在用Java解決國(guó)際化問(wèn)題的過(guò)程中,可能利用到的主要的類都是由java.util包提供的。該類包中相關(guān)的類有Locale、 ResourceBundle、ListResourceBundle、PropertyResourceBundle等,其繼承關(guān)系如下圖所示。
    其中各類提供的主要功能如下:
    Locale:該類包含對(duì)主要地理區(qū)域的地域化特征的封裝。其特定對(duì)象表示某一特定的地理、政治或文化區(qū)域。通過(guò)設(shè)定Locale,我們可以為特定的國(guó)家 或地區(qū)提供符合當(dāng)?shù)匚幕?xí)慣的字體、符號(hào)、圖標(biāo)和表達(dá)格式。例如,我們可以通過(guò)獲得特定Locale下的Calendar類的實(shí)例,顯示符合特定表達(dá)格式 的日期。
    ResourceBundle:該類是一個(gè)抽象類,需要通過(guò)靜態(tài)方法ResourceBundle.getBundle()指定具體實(shí)現(xiàn)類或?qū)傩晕募幕? 本名稱?;久Q會(huì)協(xié)同指定的或默認(rèn)的Locale類,決定具體調(diào)用的類或?qū)傩晕募奈ㄒ幻Q。例如:指定基本類或?qū)傩晕募Q為TestBundle, 而指定的Locale是CHINESE,那么最適合匹配的類名稱為TestBundle_zh_CN.class,而最佳匹配屬性文件名稱為 TestBundle_zh_CN.properties。按照J(rèn)ava Doc和相關(guān)文檔的要求,如果該類或?qū)傩晕募](méi)有找到,系統(tǒng)會(huì)查找近似匹配(主文件名依次為TestBundle_zh和TestBundle的類或?qū)傩? 文件)。該類提供的getKeys()方法用于獲得所有成員的鍵名,并提供handleGetObject方法獲得指定鍵的對(duì)應(yīng)元素。
    ListResourceBundle:該類繼承ResourceBundle類,主要是增加了一些便于操作的成分,但還是抽象類。如果希望使用類的方式實(shí)現(xiàn)具體的ResourceBundle,一般情況下最好繼承這個(gè)類。
    PropertyResourceBundle:該類也繼承ResourceBundle類,可以實(shí)例化。該類的行為特征如同java.util.properties類,可以從輸入流中獲得具體屬性對(duì)。
    如果涉及日期和時(shí)間顯示等問(wèn)題時(shí),可以利用java.text包以及java.util包中的TimeZone、SimpleTimeZone和Calendar等類進(jìn)行輔助處理。
    參數(shù)化解決方法
    在具體應(yīng)用時(shí),可以把具體國(guó)家或地區(qū)特征中可以參數(shù)化的部分放在經(jīng)過(guò)特殊命名的屬性文件中,在確定具體的Locale后,通過(guò)PropertyResourceBundle類讀取相應(yīng)的屬性文件,實(shí)現(xiàn)國(guó)際化特征。
    使用PropertyResourceBundle類獲得當(dāng)?shù)匕姹镜膰?guó)際化信息,部分代碼如下:
      ……
      public static final String BASE_PROP_FILE =
    “DISP”;
      public static final String SUFFIX =
    “.properties”;
      locale = Locale.getDefault();
      String propFile = BASE_PROP_FILE + “_” + locale.toString()+ SUFFIX;
      ResourceBundle rb;
      try {
       File file = new File(propFile);
       if (file.exists()) {
       is = new FileInputStream(file);
       rb = new PropertyResourceBundle(is);
       if (rb == null) System.out.println(“No Resource”);
       }
      } catch (IOException ioe) {
       System.out.println(“Error open file named ” + propFile);
      }
      Enumeration e = rb.getKeys();
      while (e.hasMoreElements()){
       key = (String)e.nextElement();
       value = (String)rb.handleGetObject(key);
       System.out.println(“KEY: ” + key +
    “\t\t Value: ” + value);
      }
      ……
      DISP_zh_TW.properties文件的具體內(nèi)容如下:
      Key1=\u53ef\u4ee5
      Key2=\u64a4\u9500
    等號(hào)后面是利用native2ascii程序轉(zhuǎn)化后的繁體漢字,如果不進(jìn)行轉(zhuǎn)化,系統(tǒng)可能顯示亂碼。
    處理提示和幫助
    對(duì)于提示語(yǔ)言和幫助文件部分,可以把語(yǔ)言映射放在屬性文件或者ListResourceBundle類的子類中。下面程序是一個(gè)Servlet,它通過(guò)接受客戶端的選擇,把特定語(yǔ)言和字符版本的信息返回到客戶端。
      ……
      public class ProcessServlet extends HttpServlet
      { //默認(rèn)語(yǔ)言為中文
       public static final String DEFAULT_LANGUAGE = “zh”;
       //默認(rèn)字符集為簡(jiǎn)體中文
       public static final String DEFAULT_COUNTRY = “CN”;
       public void service(HttpServletRequest req,
    HttpServletResponse res) throws IOException, ServletException {
       HttpSession session = req.getSession(true);
       // 從客戶端收到的指定語(yǔ)言和字符的參數(shù)應(yīng)當(dāng)與Sun公司相關(guān)規(guī)定一致
       String lang = req.getParameter
    (“l(fā)anguage”);
       String country = req.getParameter
    (“country”);
       if (lang == null)
        {
    //如果沒(méi)有收到參數(shù),就試圖從Session里獲得
       lang = (String) session.getAttribute
    (“l(fā)anguage”);
       country = (String) session.getAttribute
    (“country”)
       } else {
       session.setAttribute(“l(fā)anguage”, lang);
       session.setAttribute(“country”, country);
       }
       if (lang == null)
        {
    //如果無(wú)法從上述手段得到語(yǔ)言和字符信息,就使用默認(rèn)值
       lang = DEFAULT_LANGUAGE;
       country = DEFAULT_COUNTRY
       session.setAttribute(“l(fā)anguage”, lang);
        session.setAttribute(“country”, country);
       }
       Locale locale = null;
       ResourceBundle bundle = null;
       try {
       locale = new Locale(lang, country);
       } catch (Exception e) {
       System.out.println(“No locale with” +
    country + “_” + lang);
       locale = Locale.getDefault();
       }
       try {
       bundle = ResourceBundle.getBundle(
    “DisplayList”, locale);
       } catch( MissingResourceException e) {
       System.out.println( “No resources available for locale ” + locale);
       bundle = ResourceBundle.getBundle
    (“DisplayList”, Locale.US);
       }
       res.setContentType(“text/html”);
       PrintWriter out = res.getWriter();
       out.println(“<html>”);
       out.println(“<head>”);
       String title = bundle.getString(“title”);
      String welcome =bundle.getString
    (“welcome”);
       String notice = bundle.getString(“notice”);
       out.println(“<title>”+ title +
    “</title>”);
       out.println(“</head>”);
       out.println(“<body bgcolor=\”
    white\“>”);
       out.println(“<h3>” + welcome +
    “</h3>”);
       out.println(“<br>”);
       out.println(“<b>” + notice +
    “</b>”);
       out.println(“</body>”);
       out.println(“</html>”);
       }
      }
    上述Servlet使用的屬性文件(DisplayList_zh_CN.
    properties)內(nèi)容如下:
    title=中文版
    welcome=這是簡(jiǎn)體中文版面
    notice=簡(jiǎn)體中文測(cè)試成功
    注意:該文件直接采用了中文,而不是經(jīng)過(guò)轉(zhuǎn)化的Unicode編碼,這是由于大多數(shù)Web服務(wù)器不需要上述轉(zhuǎn)化。
    在實(shí)際使用中,如果Web服務(wù)器支持Servlet 2.3規(guī)范(如jakarta-tomcate 4.0),那么上面提到的Servlet應(yīng)當(dāng)稍加改變,以作為其他Servlet的處理器使用。另外,如果把ResourceBundle的特定版本存放 在無(wú)狀態(tài)會(huì)話Bean中,就可以在一定程度上提高程序效率。
    小 結(jié)
    筆者在實(shí)際測(cè)試中發(fā)現(xiàn)了如下問(wèn)題,其中部分問(wèn)題得到了解決:
    1. 對(duì)于顯示字符出現(xiàn)亂碼的問(wèn)題,如果是通過(guò)屬性文件實(shí)現(xiàn)國(guó)際化解決方案,那么可能是直接在屬性文件中寫入了非標(biāo)準(zhǔn)ASCII文字。解決方法是利用JDK提供 的工具native2ascii.exe掃描所有屬性文件,用掃描結(jié)果覆蓋原有文件內(nèi)容。如果我們是利用類文件實(shí)現(xiàn)轉(zhuǎn)換方案,那么需要重新編譯相關(guān)類文 件,并在編譯時(shí)指定編碼集。例如,編譯使用國(guó)標(biāo)碼的類文件,采用的編譯命令如下:
    javac -encoding GB2312 your_java_file
    2. 雖然Sun宣稱,在ResourceBundle類的實(shí)例化過(guò)程中,該類會(huì)查找與指定的基礎(chǔ)類絕對(duì)匹配和盡量與指定的Locale屬性相匹配的類。例如: 如果我們指定ResourceBundle基礎(chǔ)類為TestBundle,而Locale中指定使用zh_CN(中國(guó)大陸地區(qū)簡(jiǎn)體中文),那么如果系統(tǒng)找 不到TestBundle_zh_CN,系統(tǒng)應(yīng)當(dāng)順次查找TestBundle_zh、TestBundle。但是筆者在系統(tǒng)開(kāi)發(fā)過(guò)程中發(fā)現(xiàn),該匹配沒(méi)有 產(chǎn)生任何實(shí)際效果。
    筆者的測(cè)試平臺(tái)是Windows 2000 Server,沒(méi)有配置任何Service Pack,使用的JDK版本是1.3.0版本。筆者試圖通過(guò)查看JDK目錄下src.jar中附帶的源碼找到引起問(wèn)題的原因,但是發(fā)現(xiàn)有關(guān)的操作被封裝在 sun.misc包中,而src.jar文件沒(méi)有提供該包中任何類的源碼。本文把這個(gè)問(wèn)題提出來(lái),希望與有關(guān)開(kāi)發(fā)人員一起探討。
    posted on 2005-12-14 10:57 javaGrowing 閱讀(393) 評(píng)論(0)  編輯  收藏 所屬分類: java 學(xué)習(xí)
    主站蜘蛛池模板: 久久亚洲精品11p| 俄罗斯极品美女毛片免费播放| 有码人妻在线免费看片| 亚洲男人天堂影院| 久久久久亚洲精品男人的天堂| 成人免费视频小说| 18女人水真多免费高清毛片| 中文字幕在线观看免费| 亚洲AV性色在线观看| 亚洲理论片在线观看| 日本红怡院亚洲红怡院最新| 亚洲国产高清在线一区二区三区| 67194成是人免费无码| 1000部羞羞禁止免费观看视频| 中文字幕在线免费看线人| 特黄特色大片免费| 亚洲另类无码一区二区三区| 亚洲国产电影在线观看| 久久亚洲精品无码AV红樱桃| 亚洲精品乱码久久久久久久久久久久 | 亚洲第一页在线视频| 亚洲福利视频导航| 亚洲大尺度无码专区尤物| 免费人成视频x8x8入口| 国产jizzjizz免费视频| 青草草在线视频永久免费| 午夜免费不卡毛片完整版| 在线观看免费人成视频| 97碰公开在线观看免费视频| 99久久精品国产免费| 久9这里精品免费视频| 成人爽a毛片免费| 亚洲免费视频在线观看| 一区二区免费视频| 亚洲国产精品免费视频| 久久www免费人成看片| 1000部国产成人免费视频| 国产免费AV片在线播放唯爱网| 四虎永久在线精品免费观看视频| 青青青国产在线观看免费网站| 日韩欧毛片免费视频|