sjn*_*ngm 5 java resourcebundle
显然ResourceBundle需要在找到的文件中使用类似语法的属性文件.
我们有一种情况,我们想要将整个文件(在我们的例子中是HTML文件)用作"值".这意味着我们没有这样的密钥.好吧,也许文件名可以作为密钥.
这是一个目录树:
src/
main/
resources/
html/
content.html
content_de.html
content_fr.html
content_es.html
order.html
order_de.html
order_fr.html
order_es.html
Run Code Online (Sandbox Code Playgroud)
现在我们需要逻辑来根据当前的语言环境找到正确的文件.如果当前的语言环境是德语,我正在查找html/content.html文件,它应该找到html/content_de.html.它不一定需要立即加载它.Java中是否存在一些现有机制?我们需要手动完成吗?
由于某些限制,我们目前正计划不使用任何第三方库.因此,如果Java 6 SE中有可用的东西,它将是我们的最佳选择; 但是,如果您知道第三方库,请随意命名.
编辑#1:一个明显的解决方案是使用密钥messages.properties来命名该HTML文件.虽然这会起作用,但从长远来看它可能会成为一个痛苦(除此之外,我不认为这会解决我们所有的问题).
编辑#2:我忘了说这是一个桌面应用程序.
为了表明我没有做什么,这里有两次使用“我们自己”方法的尝试:
第一次尝试构建 locale-postfix 并直接加载资源:
public void attempt1(String baseName, String extension) {
List<String> locales = buildLocaleStrings(Locale.getDefault());
String resourceFound = null;
for (String locale : locales) {
String resourceName = baseName + locale + "." + extension;
URL resource = getClass().getClassLoader().getResource(resourceName);
if (resource != null) {
resourceFound = resourceName;
break;
}
}
System.out.println("found #1: " + resourceFound);
}
private List<String> buildLocaleStrings(Locale localeBase) {
String locale = "_" + localeBase;
List<String> locales = new ArrayList<String>();
while (locale.length() > 0) {
locales.add(locale);
locale = locale.replaceFirst("_[^_]*?$", "");
}
locales.add("");
return locales;
}
Run Code Online (Sandbox Code Playgroud)
第二次尝试“滥用”ResourceBundle及其toString():
public void attempt2(String baseName, final String extension) {
ResourceBundle.Control control = new ResourceBundle.Control() {
private String resourceFound = null;
@Override
public List<String> getFormats(String baseName) {
return Arrays.asList(extension);
}
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException {
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, format);
if (loader.getResource(resourceName) != null) {
resourceFound = resourceName;
return new ResourceBundle() {
@Override
public Enumeration<String> getKeys() {
return null;
}
@Override
protected Object handleGetObject(String key) {
return null;
}
};
}
return null;
}
@Override
public String toString() {
return resourceFound;
}
};
ResourceBundle.getBundle(baseName, control);
System.out.println("found #2: " + control.toString());
}
Run Code Online (Sandbox Code Playgroud)
调用示例:
public void proof() {
attempt1("html/content", "html");
attempt2("html/content", "html");
}
Run Code Online (Sandbox Code Playgroud)
两者都找到相同的文件。
说实话,我都不喜欢。