Java國際化——ResourceBundle基本使用

背景:企業項目中,往往面對國際的。針對不同地區語言,ResourceBundle主要用來處理本地化資源和國際化資源的問題,向用戶展示合理的界面顯示。

ResourceBundle

官方解釋:一堆有着相同前綴名稱但有着不同語言後綴名稱的屬性文件的集合,且至少包含2個有着相似前綴名稱的屬性文件。
用途:從適合當前用戶語言環境的資源包,一適應不同語言環境,後期提示語均在配置文件中,修改便捷。

配合Locale使用:查詢Java所支持的國家和語言,方便查詢強制化Local屬性。

package study;

import java.util.Locale;
import java.util.ResourceBundle;

public class Test {
    public static void main(String[] args) {
        Locale[] localeList = Locale.getAvailableLocales();
        //遍歷數組的每個元素,依次獲取所支持的國家和語言
        for (int i = 0; i < localeList.length ; i++ )
        {
            System.out.println(localeList[i].getCountry()+ "( "+localeList[i].getDisplayCountry() +")   "
                    +localeList[i].getLanguage()+"("+localeList[i].getDisplayLanguage()+")");

        }
}

加載順序

優先級:本地化資源(默認)>加載系統默認>加載默認的資源文件。
不存在:java.util.MissingResourceException。

本地資源構建:新建myconfig.properties相關文件
myconfig.properties:local=default
myconfig_zh_CN.properties:local=zh_CN
myconfig_en_US.properties:local=en_US

package study;
import java.util.Locale;
import java.util.ResourceBundle;
public class Test {
    public static void main(String[] args) {
        //取得系統默認的國家/語言環境
        System.out.println("=================");
        //獲取本地語言地區屬性
        System.out.println("default:"+Locale.getDefault());
        //加載默認src下,但是不能讀取其他文件加載,本class在src.study下,所以需要加前綴。
        ResourceBundle resourceBundle0 = ResourceBundle.getBundle("study.myconfig");
        System.out.println(resourceBundle0.getString("local"));
        System.out.println("=================");
        //中文測試
        Locale locale1 = new Locale("zh", "CN");
        ResourceBundle resourceBundle1 = ResourceBundle.getBundle("study.myconfig",locale1);
        System.out.println(resourceBundle1.getString("local"));
        System.out.println("=================");
        //英文測試
        Locale locale2 = new Locale("en", "US");
        ResourceBundle resourceBundle2 = ResourceBundle.getBundle("study.myconfig",locale2);
        System.out.println(resourceBundle2.getString("local"));
        System.out.println("=================");
         //德文測試,但不存在該語言的Properties
        Locale locale3 = new Locale("de", "GR");
        ResourceBundle resourceBundle3 = ResourceBundle.getBundle("study.myconfig",locale3);
        System.out.println(resourceBundle3.getString("local"));
}

    

測試結果:配置文件都存在.png
順序:對於中國用戶:中國>默認。英國用戶:英國>默認。 德國:中國>默認(德國不存在,但是不是直接走默認,而是先走中國,中國是本地化資源!!!)
特別:
1.屬性key-value,若上級資源中沒有key,則去下級資源中尋找。
2.優先走本地化資源文件。若不存在,則走不帶後綴文件,本地化資源文件不等於默認不帶後綴的配置文件。

刪除myconfig_zh_CN.properties:

本地資源不存在.png
順序:對於中國用戶:默認。英國用戶:英國>默認。 德國:默認(德國不存在,但是不是直接走默認,而是先走中國,中國是本地化資源!!!)

其他注意:
報錯:Can’t find bundle for base name myconfig, locale xx_XX。查找文件路徑是否正確。

  • 直接配置,src下讀取,但是內部文件夾,需要前綴讀取。
  • src路徑下的文件在編譯後會放到WEB-INF/clases路徑下(默認的classpath)
  • 直接放到WEB-INF下的話,是不在classpath下的

編碼:

底層讀取Properties文件是根據字節流的形式,防止中文亂碼,建議配置文件存在中文等,使用Unicode字符集進行配置。
源碼片段:

 else if (format.equals("java.properties")) {
                final String resourceName = toResourceName0(bundleName, "properties");
                if (resourceName == null) {
                    return bundle;
                }
                final ClassLoader classLoader = loader;
                final boolean reloadFlag = reload;
                InputStream stream = null;
                try {
                    stream = AccessController.doPrivileged(
                        new PrivilegedExceptionAction<InputStream>() {
                            public InputStream run() throws IOException {
                                InputStream is = null;
                                if (reloadFlag) {
                                    URL url = classLoader.getResource(resourceName);
                                    if (url != null) {
                                        URLConnection connection = url.openConnection();
                                        if (connection != null) {
                                            // Disable caches to get fresh data for
                                            // reloading.
                                            connection.setUseCaches(false);
                                            is = connection.getInputStream();
                                        }
                                    }
                                } else {
                                    is = classLoader.getResourceAsStream(resourceName);
                                }
                                return is;
                            }
                        });
                } catch (PrivilegedActionException e) {
                    throw (IOException) e.getException();
                }
               

經驗

1.可以通過只配置myconfig.properties來全局變量,不配置其他語言文件。
2.企業項目中,配合PropertyUtils,設置map.properties,不打包,當國際化各個配置文件找不到相應提示,提供一個類別管理的報錯。
3.編碼問題請使用Unicode字符集輸入,可以使用在線轉碼工具也可以配合java自帶的native2ascii.exe
4.配合NumberFormat ,DateFormat進行String處理

補充

Properties補充:
https://www.cnblogs.com/alfredinchange/p/5384760.html
ResourceBundle運行會自行將配置文件打包,也可以根據情況自己配合idea打包:https://segmentfault.com/a/1190000016496715
Spring相關:https://blog.csdn.net/u010882791/article/details/83756717

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章