加载所有 ResourceBundle 并根据密钥和区域设置选择正确的资源
Load all ResourceBundles and pick correct resource based on key and Locale
好的,所以我面临的挑战是实施一个 "Service" 加载我们支持的所有语言环境的所有资源。然后应该可以根据键和当前的 Locale 从正确的 ResourceBundle 中选择资源。我怎样才能做到这一点?
这就是我制定解决方案的方式,我有一个名为 TranslationService
的 Service
public class TranslationService {
private List<ResourceBundle> resourceBundles;
public TranslationService(final Locale locale) {
ResourceBundle messageTexts = ResourceBundle.getBundle("MessageTexts", locale, new Utf8Control());
ResourceBundle notificationTexts = ResourceBundle.getBundle("NotificationTexts", locale, new Utf8Control());
ResourceBundle generalTexts = ResourceBundle.getBundle("GeneralTexts", locale, new Utf8Control());
Collections.addAll(this.resourceBundles, messageTexts, notificationTexts, generalTexts);
}
public String getText(String key) {
String text = null;
for (ResourceBundle resourceBundle : resourceBundles) {
try {
text = resourceBundle.getString(key);
} catch (MissingResourceException e) {
// DO NOTHING: If the key is not found in first resource means not that it isn't in the next
// check all resources for the key.
}
}
if (text == null) {
log.error("Could not find key {} in any resource.", key);
}
return text;
}
}
所以我想要实现的是能够为所有支持的 Locales
加载所有指定的 Bundles
所以说我想在初始化前加载 MessageTexts_en_GB.properties
、MessageTexts_fr_FR.properties
、MessageTexts_ja_JP.properties
等。然后根据使用的语言环境和我发送的密钥,我应该能够知道在哪个 Bundle 中寻找密钥,而无需遍历我的所有 Bundle .也就是说,如果我得到 fr_FR
的 Locale
和 key
PUSH_NOTIFICATION_REMINDER
,那么我就知道我必须在 NotificationTexts_fr_FR.properties
中查找文本而不必须像我一样遍历所有资源。那么是否有可能这样做,或者我是否必须像现在这样遍历我的所有资源,如果可以为所有语言环境加载资源,我最终将如何处理 属性 命名冲突,所以我没有听错语言 属性?
所以我目前正在研究如下所示的解决方案:
public class MyResourceBundle {
private Map<Locale, Map<String, String>> localeResources;
public MyResourceBundle() {
localeResources = new HashMap<>();
for (LocaleConfig config : LocaleConfig.values()) {
Map<String, String> resources = new HashMap<>();
ResourceBundle systemTexts = ResourceBundle.getBundle("SystemTexts", config.getLocale());
ResourceBundle translationTexts = ResourceBundle.getBundle("TranslationTexts", config.getLocale());
Enumeration systemKeys = systemTexts.getKeys();
while (systemKeys.hasMoreElements()) {
String key = (String) systemKeys.nextElement();
resources.put(key, systemTexts.getString(key));
}
Enumeration translationKeys = translationTexts.getKeys();
while (translationKeys.hasMoreElements()) {
String key = (String) translationKeys.nextElement();
resources.put(key, translationTexts.getString(key));
}
localeResources.put(config.getLocale(), resources);
}
}
public String getText(Locale locale, String key) {
String text = null;
text = localeResources.get(locale).get(key);
if (text == null) {
String errorMessage = "Key: " + key + " does not exist for locale " + locale.toString();
throw new MissingResourceException(errorMessage, this.getClass().getName(), key);
}
return text;
}
}
LocaleConfig.java :
public enum LocaleConfig {
DANISH("da", "DK"),
ENGLISH("en", "GB")
;
private String language;
private String country;
LocaleConfig(String language, String country) {
this.language = language;
this.country = country;
}
public Locale getLocale() {
return new Locale(language, country);
}
}
SystemTexts_da_DK.properties:
PERSON_1=Hans Hansen
PERSON_2=Anders Andersen
PERSON_3=Ib Ibsen
REMINDER_MESSAGE=Husk at teste...
SystemTexts_en_GB.properties:
PERSON_1=Frank Testerson
PERSON_2=Julie Testerson
PERSON_3=Test Testerson
REMINDER_MESSAGE=Remember to test...
TranslationTexts_da_DK.properties:
NOTE_NEW=Ny
NOTE_SEEN=Set
TranslationTexts_en_GB.properties:
NOTE_NEW=New
NOTE_SEEN=Seen
现在我可以打电话了:
public class MyResourceBundleExample {
public static void main(String[] args) {
Locale locale = new Locale("da", "DK");
MyResourceBundle myResourceBundle = new MyResourceBundle();
System.out.println(myResourceBundle.getText(locale, "PERSON_3"));
}
}
对该解决方案的初步测试表明它可以正常工作,但如果有人有更好的解决方案或更流畅的方法,我会洗耳恭听:)。
好的,所以我面临的挑战是实施一个 "Service" 加载我们支持的所有语言环境的所有资源。然后应该可以根据键和当前的 Locale 从正确的 ResourceBundle 中选择资源。我怎样才能做到这一点?
这就是我制定解决方案的方式,我有一个名为 TranslationService
Service
public class TranslationService {
private List<ResourceBundle> resourceBundles;
public TranslationService(final Locale locale) {
ResourceBundle messageTexts = ResourceBundle.getBundle("MessageTexts", locale, new Utf8Control());
ResourceBundle notificationTexts = ResourceBundle.getBundle("NotificationTexts", locale, new Utf8Control());
ResourceBundle generalTexts = ResourceBundle.getBundle("GeneralTexts", locale, new Utf8Control());
Collections.addAll(this.resourceBundles, messageTexts, notificationTexts, generalTexts);
}
public String getText(String key) {
String text = null;
for (ResourceBundle resourceBundle : resourceBundles) {
try {
text = resourceBundle.getString(key);
} catch (MissingResourceException e) {
// DO NOTHING: If the key is not found in first resource means not that it isn't in the next
// check all resources for the key.
}
}
if (text == null) {
log.error("Could not find key {} in any resource.", key);
}
return text;
}
}
所以我想要实现的是能够为所有支持的 Locales
加载所有指定的 Bundles
所以说我想在初始化前加载 MessageTexts_en_GB.properties
、MessageTexts_fr_FR.properties
、MessageTexts_ja_JP.properties
等。然后根据使用的语言环境和我发送的密钥,我应该能够知道在哪个 Bundle 中寻找密钥,而无需遍历我的所有 Bundle .也就是说,如果我得到 fr_FR
的 Locale
和 key
PUSH_NOTIFICATION_REMINDER
,那么我就知道我必须在 NotificationTexts_fr_FR.properties
中查找文本而不必须像我一样遍历所有资源。那么是否有可能这样做,或者我是否必须像现在这样遍历我的所有资源,如果可以为所有语言环境加载资源,我最终将如何处理 属性 命名冲突,所以我没有听错语言 属性?
所以我目前正在研究如下所示的解决方案:
public class MyResourceBundle {
private Map<Locale, Map<String, String>> localeResources;
public MyResourceBundle() {
localeResources = new HashMap<>();
for (LocaleConfig config : LocaleConfig.values()) {
Map<String, String> resources = new HashMap<>();
ResourceBundle systemTexts = ResourceBundle.getBundle("SystemTexts", config.getLocale());
ResourceBundle translationTexts = ResourceBundle.getBundle("TranslationTexts", config.getLocale());
Enumeration systemKeys = systemTexts.getKeys();
while (systemKeys.hasMoreElements()) {
String key = (String) systemKeys.nextElement();
resources.put(key, systemTexts.getString(key));
}
Enumeration translationKeys = translationTexts.getKeys();
while (translationKeys.hasMoreElements()) {
String key = (String) translationKeys.nextElement();
resources.put(key, translationTexts.getString(key));
}
localeResources.put(config.getLocale(), resources);
}
}
public String getText(Locale locale, String key) {
String text = null;
text = localeResources.get(locale).get(key);
if (text == null) {
String errorMessage = "Key: " + key + " does not exist for locale " + locale.toString();
throw new MissingResourceException(errorMessage, this.getClass().getName(), key);
}
return text;
}
}
LocaleConfig.java :
public enum LocaleConfig {
DANISH("da", "DK"),
ENGLISH("en", "GB")
;
private String language;
private String country;
LocaleConfig(String language, String country) {
this.language = language;
this.country = country;
}
public Locale getLocale() {
return new Locale(language, country);
}
}
SystemTexts_da_DK.properties:
PERSON_1=Hans Hansen
PERSON_2=Anders Andersen
PERSON_3=Ib Ibsen
REMINDER_MESSAGE=Husk at teste...
SystemTexts_en_GB.properties:
PERSON_1=Frank Testerson
PERSON_2=Julie Testerson
PERSON_3=Test Testerson
REMINDER_MESSAGE=Remember to test...
TranslationTexts_da_DK.properties:
NOTE_NEW=Ny
NOTE_SEEN=Set
TranslationTexts_en_GB.properties:
NOTE_NEW=New
NOTE_SEEN=Seen
现在我可以打电话了:
public class MyResourceBundleExample {
public static void main(String[] args) {
Locale locale = new Locale("da", "DK");
MyResourceBundle myResourceBundle = new MyResourceBundle();
System.out.println(myResourceBundle.getText(locale, "PERSON_3"));
}
}
对该解决方案的初步测试表明它可以正常工作,但如果有人有更好的解决方案或更流畅的方法,我会洗耳恭听:)。