(spring-第14回【IoC基礎篇】)國際化信息

来源:http://www.cnblogs.com/mesopotamia/archive/2016/01/10/5117727.html
-Advertisement-
Play Games

國際化信息又稱為本地化信息,由語言類型(如zh)和國家/地區類型來限定(如CN)。java.util.Locale是創建國際化的基礎類。spring管理國際化定義了MessageSource介面。ResourceBundleMessageSource實現了MessageSource介面。


  國際化又稱為本地化。 

  當你把手機的language由中文切換到英文時,你的微信也相應改用英語,這就是i18n國際化。一般來說,應用軟體提供一套不同語言的資源文件,放到特定目錄中,應用根據不同語言的操作系統決定使用哪一種語言。

  一般由兩個條件限定一個國際化類型:語言類型和國家/地區類型。比如:

  中文:語言類型:zh,國家/地區類型:CN(中國大陸)/HK(中國香港)/TW(中國臺灣)。

  英語:語言類型:en,國家類型:EN。

----------------------------------------------------------------------------------------------------------------

  java.util.Locale是一個本地化類,是創建國際化應用的基礎。

  創建本地化對象有多種方式:Locale locale1=new Locale("zh","CN");//倆參,語言類型、國家類型

               Locale locale2=new Locale("zh");//預設本地語言類型

                 Locale locale3=Locale.CHINA;//常量

               Locale locale4=Locale.getDefault();//預設的本地化對象。

  

  -------------------------------------------------------------------------------------------------------

     光有本地化類還不行,需要有個利用本地化對象來操作輸出信息的類:

  java.text包中提供了幾個這樣的工具類:DateFormat、MessageFormat、NumberFormat。

      

----------------------------------------------------------------------------------------------------  

  NumberFormat舉例:給一個123456.78,把它輸出為¥123456.78,即把數字轉換為貨幣格式。

1      Locale locale = new Locale("zh","CN");
2         NumberFormat nf=NumberFormat.getCurrencyInstance(locale);
3         System.out.println("一頭羊售價:"+nf.format(d));
public static void main(String args[]){
        printCurrency(888.88);
    }

 

列印:一頭羊售價:¥888.88

-------------------------------------------------------------------------------------------------------

DateFormat舉例:給一個當前時間Date()對象,把它轉換成英文格式。

public static void printUSDate(Date date){
        Locale locale=new Locale("en","US");
        DateFormat df=DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
        System.out.println(df.format(date));
    }
    
    
    public static void main(String args[]){
        printUSDate(new Date());
    }

列印:Jan 10, 2016。

上面的DateFormat.MEDIUM是啥?java源碼註釋:

  /**
     * Constant for long style pattern.
     */
    public static final int LONG = 1;
    /**
     * Constant for medium style pattern.
     */
    public static final int MEDIUM = 2;
    /**
     * Constant for short style pattern.
     */
    public static final int SHORT = 3;
    /**
     * Constant for default style pattern.  Its value is MEDIUM.
     */
    public static final int DEFAULT = MEDIUM;

把參數DateFormat.MEDIUM改成DateFormat.LONG,列印:January 10, 2016。

 

-------------------------------------------------------------------------------------------------------

MessageFormat:增加占位符功能。

什麼是占位符功能?比如:我定義一個字元串:昨天{0}在{1}睡覺呢。傳參{"小明","家"},那麼列印:昨天小明在家睡覺呢。傳參:{"大鵬","學校"},那麼列印:昨天大鵬在學校睡覺呢。

舉例1:銀行給John說:John您好,你於XXX在招商銀行存入XX元。不同時間,銀行又對David說:David您好,你於XXX在招商銀行存入XX元。信息相同,使用MessageFormat。參數信息可以動態改變。

public static void printBankNotice(Object[] params){
        String pattern1="{0},你好,你於{1}在招商銀行存入{2}元。";
        String message1=MessageFormat.format(pattern1, params);
        System.out.println(message1);
    }
    
    public static void main(String args[]){
        printBankNotice(new Object[]{"John",new GregorianCalendar().getTime(),1.0E3});
    }

列印:John,你好,你於16-1-10 上午2:24在招商銀行存入1,000元。

占位符功能還能對參數格式作適當的轉換,參數順序也可以靈活調整。

public static void printBankNotice2(Object[] params){
        String pattern2="At{1,time,short} on{1,date,long},{0} paid {2,number,currency}.";
        MessageFormat mf=new MessageFormat(pattern2,Locale.US);
        System.out.println(mf.format(params));
    }
    
    public static void main(String args[]){
        printBankNotice2(new Object[]{"John",new GregorianCalendar().getTime(),1.0E3});
    }

列印:At2:32 AM onJanuary 10, 2016,John paid $1,000.00.

---------------------------------------------------------------------------------------------------

應用程式中需要國際化,則使用java.util.ResourceBundle

舉例:定義一個英文的屬性文件和一個中文的屬性文件,裡面放一些問候語,根據程式的需要選擇不同語言的問候語。

步驟:

1.在程式的特定位置定義兩個properties文件,一個是中文的,一個是英文的,名稱格式為:

<資源名>_<語言代碼>_<國家/地區編碼>.properties

 

  resource_en_US.properties內容:

greeting.common=How are you!
greeting.morning = Good morning!
greeting.afternoon =Good Afternoon\!

resource_zh_CN.properties內容:

greeting.common=\u60A8\u597D\uFF01
greeting.morning=\u65E9\u4E0A\u597D\uFF01
greeting.afternoon=\u4E0B\u5348\u597D\uFF01

(資源文件只能包含ASCII字元,所以你這樣寫了,程式運行時需要把這樣的字元轉換成Unicode的表示形式。但是這樣編寫我們不熟悉,也不現實,所以,MyEclipse提供了屬性編輯器,可以方便我們寫中文):

切換到Properties視窗:

在這裡編寫就好。

接下來使用ResourceBundle。

public static void resourceBoundle(){
        ResourceBundle rb1 = ResourceBundle.getBundle("com/baobaotao/i18n/resource",Locale.US);
        ResourceBundle rb2 = ResourceBundle.getBundle("com/baobaotao/i18n/resource",Locale.CANADA);
        System.out.println("us:"+rb1.getString("greeting.common"));
        System.out.println("cn:"+rb2.getString("greeting.common"));
    }

上文講到了占位符功能,在這裡,你也可以把properties文件的屬性值寫成占位符形式,然後用ResourceBundle結合MessageFormat實現國際化字元串的動態改變。

---------------------------------------------------------------------------------------------------------

Spring的國際化

spring定義了MessageSource介面來實現國際化,它引入了java.util.Locale,並用getMessage方法載入國際化信息。也就是說,spring國際化的原理還是引用了上面講的java的那一套,不過把它引入到了spring容器中。

類圖結構:

根據繼承關係我們看到,ResourceBundleMessageSource、ReloadableResourceBundleMessageSource、ApplicationContext都具有MessageSource功能。

-----------------------------------------------------------------------------------------------------------------------------------------------

ResourceBundleMessageSource是spring一般的國際化方法類。使用也很簡單,

在XML中註冊該類,容器啟動時就會實例化該類:

 <bean id="myResource1" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
       <list>
         <value>com/baobaotao/i18n/fmt_resource</value>
       </list>
    </property>
  </bean> 

list裡面可以放多個properties文件,這裡fmt_resource是一個通用名,包含了該名下所有的properties文件,

在代碼中,啟動spring容器,載入MessageSource,定義格式化串,調用getMessage就可以了:

private static void rsrBdlMessageResource(){
        
        String[] configs = {"com/baobaotao/i18n/beans.xml"};
        ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);
        //步驟1:獲取MessageSource實例化對象
        MessageSource ms = (MessageSource)ctx.getBean("myResource1");
        //步驟2:定義格式化串
        Object[] params = {"John", new GregorianCalendar().getTime()};
        //步驟3:調用getMessage方法啊
        String str1 = ms.getMessage("greeting.common",params,Locale.US);
        String str2 = ms.getMessage("greeting.morning",params,Locale.CHINA);
        String str3 = ms.getMessage("greeting.afternoon",params,Locale.CHINA);
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
        
    }

-------------------------------------------------------------------------------------------------

ReloadableResourceBundleMessageSource

跟ResourceBundleMessageSource相比,它多了一個定時刷新功能,即,系統在不重啟的情況下,修改properties文件,使用ReloadableResourceBundleMessageSource重新載入(定時)。

在XML中註冊bean的時候加一個定時屬性就可以了:

 <bean id="myResource2" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
       <list>
         <value>com/baobaotao/i18n/fmt_resource</value>
       </list>
    </property>
    <property name="cacheSeconds" value="2"/>
  </bean>  

---------------------------------------------------------------------------------------------------------

ApplicationContext的國際化功能:

ApplicationContext屬於容器級,它賦予了國際化信息功能,是因為國際化信息常常作為容器的公共基礎設施對所有組件開放。

使用容器級國際化很簡單,針對ResourceBundleMessageSource作一點點修改:

配置文件上的修改:

 <bean id="mySource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
       <list>
         <value>com/baobaotao/i18n/fmt_resource</value>
       </list>
    </property>
  </bean> 

代碼修改:

去掉getBean步驟,直接用ctx.getMessage獲取字元串。

------------------------------------------------------------------------------------------------------

總結:

  1. 國際化信息又稱為本地化信息,由語言類型(如zh)和國家/地區類型來限定(如CN)。
  2. java.util.Locale是創建國際化的基礎類。
  3. NumberFormat(對數字轉換成特定格式)、DateFormat(對日期輸出為特定格式)、MessageFormat(使用占位符)等是操作國際化的工具類。
  4. 使用ResourceBundle類處理針對國際化的properties文件(命名規則有限定,如resource_en_US.properties)。
  5. spring管理國際化定義了MessageSource介面。
  6. ResourceBundleMessageSource實現了MessageSource介面。
  7. ReloadableResourceBundleMessageSource實現了MessageSource介面,多了定時更新國際化信息的功能。
  8. ApplicationContext實現了MessageSource介面,把國際化信息上升到了容器級。

 

 

玉不琢,不成器;人不學,不知道。——《禮記·學記》

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前幾天把CurrencyExchanger提交到微軟參加Master認證,結果沒有通過,反饋了一些錯誤,看來微軟檢查還是比較仔細的。錯誤主要有:Visual feedback helps users recognize whether their interactions with your app...
  • 題目:Given preorder and inorder traversal of a tree, construct the binary tree.Note:You may assume that duplicates do not exist in the tree.思路:遞歸,preord...
  • 題目:Given a binary tree, find its maximum depth.The maximum depth is the number of nodes along the longest path from the root node down to the farthest...
  • 題目:Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example:Given binary tree...
  • 題目:Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).For example, this binary tree is symmetric: 1 / ...
  • 題目:Given two binary trees, write a function to check if they are equal or not.Two binary trees are considered equal if they are structurally identical...
  • 題目大意:平面上有n個點,兩兩不同。現在給出二叉樹的定義,要求樹邊一定是從上指向下,即從y坐標大的點指向小的點,並且每個結點至多有兩個兒子。現在讓你求給出的這些點是否能構成一棵二叉樹,如果能,使二叉樹的樹邊長度(歐幾里德長度)總和最小,輸出這個總和。如果不能,輸出-1.答案與標準答案相差1e-6內都...
  • 假設某 POJO 有屬性如下: private Set users = new HashSet(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "xuser") public Set getUsers() { return this.users; ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...