我有一个现有的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)
有更好的想法吗?
答案 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>