S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

ResourceBundleによるプロパティファイルでの多言語対応

SunのJava1.5では、java.util.ResourceBundle#getBundleロケールを指定して、リソースを取得しようとした場合。
もし、言語(と国)が一致するリソースが存在しなければ、デフォルトのロケールを使ってリソースを取得してしまう。


仮にリソースとして、

【Messages.properties】
key=test

【Messages_jp.properties】
key=テスト

を定義していた場合。

ResourceBundle jprb = ResourceBundle.getBundle("Messages", new Locale("ja", "JP"));
ResourceBundle enrb = ResourceBundle.getBundle("Messages", new Locale("en", "US"));
ResourceBundle zhrb = ResourceBundle.getBundle("Messages", new Locale("zh", "CN"));
System.out.println(jprb.getLocale() + " > " + jprb.getString("key"));
System.out.println(enrb.getLocale() + " > " + enrb.getString("key"));
System.out.println(zhrb.getLocale() + " > " + zhrb.getString("key"));

を実行すると、ja_JPがデフォルトのローケールのため、

ja > テスト
ja > テスト
ja > テスト

となる。


もちろん

【Messages_en.properties】
key=test

を定義すると、

ja > テスト
en > test
ja > テスト

となる。
このような動作では、例えば日本語だけ定義しておいて、それ以外は全部英語としたい場合など、「Messages.propertiesに、英語のメッセージを設定しておけば、日本以外のロケールの場合は英語になる」というような、動作をさせることができない。


Java6では、ITpro > 「Java SE 6完全攻略」第54回 ResourceBundleの新機能 その2 にあるとおり、

ResourceBundle.Control control = 
                ResourceBundle.Control.getNoFallbackControl(
                                            ResourceBundle.Control.FORMAT_DEFAULT
                                            );
ResourceBundle jprb = ResourceBundle.getBundle("Messages", new Locale("ja", "JP"), control);
ResourceBundle enrb = ResourceBundle.getBundle("Messages", new Locale("en", "US"), control);
ResourceBundle zhrb = ResourceBundle.getBundle("Messages", new Locale("zh", "CN"), control);
System.out.println(jprb.getLocale() + " > " + jprb.getString("key"));
System.out.println(enrb.getLocale() + " > " + enrb.getString("key"));
System.out.println(zhrb.getLocale() + " > " + zhrb.getString("key"));

とすることで、

ja > テスト
en > test
 > test

という結果が得られる。


同様の挙動は、Java1.5以前のバージョンでは、下記のようなメソッドで実現できそう。

public static ResourceBundle getBundle(String res, Locale locale) {
    ResourceBundle bundle = ResourceBundle.getBundle(res, locale);
    if (bundle.getLocale().getLanguage().equals(locale.getLanguage()) == true) {
        return bundle;
    }
    return  ResourceBundle.getBundle(res, new Locale("", ""));
}