3

リソース バンドルから文字列を取得するために、コードの例の下にあるこの 2 つのメソッドの結果を比較しようとしています。

最初の例:

baseName: リソース バンドルの完全修飾名 ( <base-name>in <resource-bundle>)。

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle bundle = app.getResourceBundle(context, baseName);

2 番目の例:

<var></var>varName: in を表す文字列です。<resource-bundle>

FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context .getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(varName, locale, loader);

これらの 2 つの例の違いは何ですか? 違いがない場合、 ResourceBundle を取得するためのベストプラクティスは何ですか ( Application#getMessageBundle() または ResourceBundle#getBundle() を使用するため) ?

4

1 に答える 1

9

まず、アプローチの varName/baseName を混同しました。実際のアプローチは次のとおりです。

Application#getResourceBundle()

varName<resource-bundle><var>: in を表す文字列です。faces-config.xml

FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ResourceBundle bundle = application.getResourceBundle(context, varName);

ResourceBundle#getBundle()

baseName: は、リソース バンドルの完全修飾名です。<resource-bundle><base-name>

FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context.getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, loader);

前者は JSF を介して取得しますが、これは内部で( へのフォールバックを使用して)Applicationも使用しますが、後者は直接取得します。UIViewRoot#getLocale()Locale#getDefault()

技術と最終結果に関しては、違いはありません。どちらの場合でもまったく同じバンドルを取得できます (ロケールが正しい場合)。ただ、メンテナンス性に関しては、断然違います。リソース バンドルは「構成」に分類され、( で) 外部化する必要がありますfaces-config.xml

のように FQN をハードコーディングすることは、お勧めできませんbaseName。すべてのコードを再コンパイルして再構築しなければ、FQN を簡単にすばやく変更することはできません。サードパーティの JAR ファイルに含まれていた場合は、さらに面倒です。それ以外の場合は、webapp 内から別<resource-bundle>の同じものでオーバーライドすることができます。<var>また、JSF コンポーネント/ユーティリティ ライブラリは独自のApplicationラッパーを提供する場合がありgetResourceBundle()ます。経由で直接取得した場合、それは不可能ですResourceBundle#getBundle()


ちなみに、3 番目のアプローチがあります。注入するだけです。

JSF マネージド Bean で、以下を提供<var>text</var>:

@ManagedProperty("#{text}")
private ResourceBundle text;

または、CDI マネージド Bean で:

@Inject
private PropertyResourceBundle text;

このプロデューサーでは:

public class BundleProducer {

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
    }

}

注:#{text}バンドルの EL 評価はカバーの下で使用されますApplication#getResourceBundle()

于 2015-01-13T22:06:42.973 に答える