3

为了从资源包中检索字符串,我试图比较这两种方法的结果,下面是代码示例:

第一个例子:

baseName:资源包的完全限定名称 ( <base-name>in <resource-bundle>)。

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

第二个例子:

varName:是代表<var></var>in的String<resource-bundle>

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

这两个例子有什么区别?如果没有区别,获得 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)。

硬编码 FQNbaseName是一种不好的做法。如果不重新编译和重新构建所有代码,您将无法轻松快速地更改 FQN。如果是在 3rd 方 JAR 文件中,那就更麻烦了。否则,您可以在您的 web 应用程序内部用另一个<resource-bundle>相同的方法覆盖它。<var>此外,JSF 组件/实用程序库可能会提供一个自己的Application包装器,该包装器可能会装饰getResourceBundle()调用以做一些很棒的事情。如果您直接通过ResourceBundle#getBundle().


顺便说一句,还有第三种方法:注入它。

在 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);
    }

}

注意: EL 评估#{text}捆绑使用的幕后Application#getResourceBundle()

于 2015-01-13T22:06:42.973 回答