PropertyResourceBundleから一部のリソースをオーバーライドする方法
-
19-08-2019 - |
質問
既存のJava / JSF Webサイトがあり、画面上のすべてのテキストは<!> lt; f:loadBundle basename = <!> quot; org.example.applicaltion <!> quot;を介してプロパティファイルから取得されます。 var = <!> quot; applicaltion <!> quot; / <!> gt; applicaltion.propertiesからテキストを取得します。
これらのランタイム構成可能サブセットの場合、他の場所から文字列を取得したい(Webサービス経由のCMS)。 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
}
}
これを試しましたが、親はnullです。これは、デフォルトの場合に使用されると思われます-<!> gt; en-<!> gt; en_GB。
プロパティファイルにカスタムresourceBundleとは異なる名前を付け、CustomResourceBundle.handleGetObject(key)内からResourceBundle.getBundle(PROPERTY_FILE_NAME).getString(key)のフルスタックを委任するというあまり魅力的ではないオプションを検討しています。
より良いアイデアはありますか
解決
これを解決するために、オーバーライド値があるかどうかを確認し、それを返した場合はチェックし、そうでない場合は標準リソースバンドルに委任しました
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ローダーは再帰的になりません。
他のヒント
カスタムPropertyResolverを記述し、それからプロパティ値を取得する場所のロジックを実行させることができます。
たとえば、messageSource
というBeanを定義し、application.propertiesに加えてCMSプロパティなどをロードすることができます。
カスタムPropertyResolver
を作成します(SpringのMessageSource でこれを行う方法の例がありますここ)、次のようなものを使用してfaces-config.xml
にリンクします:
<application>
<property-resolver>
com.package.MessageSourcePropertyResolver
</property-resolver>
</application>