如何覆盖PropertyResourceBundle中的一些资源

时间:2009-03-17 10:33:18

标签: java resourcebundle

我有一个现有的Java / JSF网站,屏幕上的所有文字都来自属性文件,通过< f:loadBundle basename =“org.example.applicaltion”var =“applicaltion”/>它从applicaltion.properties中提取文本。

对于这些运行时可配置的子集,我想从其他位置(CMS通过Web服务)拉取字符串。查看ResourceBundle类,它可以通过委托父ResourceBundle来获得与此相近的基础设施。

我想要像这样的一些

public class Applicaltion extends ResourceBundle{
    @Override
protected Object handleGetObject(String key) {
    if(overridenKey(key)){
        return overridedValue(key);
    }
    return null; // ResourceBundle.getObject will delegate to parent 
             // if we return null
}
}

我试过这个并且parent为null,我认为这更多用于默认情况 - > en - > EN_GB。

我正在考虑一个不太吸引人的选项,让属性文件与自定义resourceBundle具有不同的名称,然后从CustomResourceBundle.handleGetObject(key)中委托完整堆栈的ResourceBundle.getBundle(PROPERTY_FILE_NAME).getString(key)

有更好的想法吗?

2 个答案:

答案 0 :(得分:2)

我最后通过检查是否有覆盖值来解决这个问题,如果我们确实返回了它,否则委托给标准资源包

public class UILabels extends ResourceBundle {


private ResourceBundle getFileResources(){
    return ResourceBundle.getBundle("com.example.web.UILabelsFile", this.getLocale());
}

public Enumeration<String> getKeys() {
    return getFileResources().getKeys();
}

protected Object handleGetObject(String key) {
    if(overrideValue(key)){
        return getOverridenValue(key);
    }
    return getFileResources().getObject(key);
}

}

注意名称类的细微差别是UILabels,所有客户端将使用该文件的是UILabelsFile,因此ResourceBundle加载器不会递归。

答案 1 :(得分:0)

您可以编写自定义PropertyResolver,然后执行从中提取属性值的逻辑。

例如,您可以定义一个名为messageSource的bean,并加载application.properties,加上您的CMS属性或您拥有的任何内容。

然后编写一个自定义PropertyResolver(有一个如何使用Spring的MessageSource here执行此操作的示例)并使用以下内容将其链接到faces-config.xml

<application>  
<property-resolver>  
      com.package.MessageSourcePropertyResolver  
   </property-resolver>  
</application>