在我正在进行的项目中,我想根据当前的语言环境加载不同的资源。使用字符串,这非常简单:只需通过添加一些文件创建资源包,例如 Localization.properties
和 Localization_de.properties
,然后通过 ResourceBundle 加载它.getBundle("domain.project.Localization")
.
但是如何加载非简单字符串的本地化资源?
具体来说,我想根据区域设置加载图像和 HTML 文件。获取该资源的正确 URL 就足够了。例如,我想要一个 Welcome.html
和 Welcome_de.html
文件,并在当前语言环境为德语时加载后者。
简单地使用 getClass().getResource("Welcome.html")
是行不通的,它总是准确地返回那个文件并且不进行语言环境处理。除了根据当前语言环境手动修改文件名之外,我还没有找到解决这个问题的便捷方法。
我想出的一个解决方案是在我的 Localization.properties
文件中添加一个 key ,其中包含正确的本地化 HTML 文件的名称。但这感觉很老套而且是错误的。
请注意,这不是 Android 应用程序,只是一个标准的 Java 8 桌面应用程序。
最佳答案
事实证明,获得与 ResourceBundle.getBundle
相同的行为非常容易。我有 looked at the code并发现处理语言环境和文件名的最重要部分是 ResourceBundle.Control .
所以这里有一个简单的方法,可以将 URL 返回到本地化资源(遵循与资源包相同的文件名方案),而无需缓存并仅支持当前语言环境:
/** Load localized resource for current locale.
*
* @param baseName Basename of the resource. May include a path.
* @param suffix File extension of the resource.
* @return URL for the localized resource or null if none was found.
*/
public static URL getLocalizedResource(String baseName, String suffix) {
Locale locale = Locale.getDefault();
ResourceBundle.Control control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
List<Locale> candidateLocales = control.getCandidateLocales(baseName, locale);
for (Locale specificLocale : candidateLocales) {
String bundleName = control.toBundleName(baseName, specificLocale);
String resourceName = control.toResourceName(bundleName, suffix);
// Replace "Utils" with the name of your class!
URL url = Utils.class.getResource(resourceName);
if (url != null) {
return url;
}
}
return null;
}
如果有人想扩展它以支持通用语言环境作为参数:ResourceBundle.getBundleImpl
实现中的重要部分是:
for (Locale targetLocale = locale;
targetLocale != null;
targetLocale = control.getFallbackLocale(baseName, targetLocale)) {
List<Locale> candidateLocales = control.getCandidateLocales(baseName, targetLocale);
...
}
getCandidateLocales
的最后一个条目是空语言环境 (Locale.ROOT
)。当区域设置时应该忽略它,因为在测试后备区域设置之前,默认资源将在第一个 for
迭代中找到。
关于java - 加载本地化资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27886490/