jsf - JSF 2.0 中 Application#getResourceBundle() 和 ResourceBundle#getBundle() 之间的区别

标签 jsf jsf-2 resourcebundle facescontext

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

第一个例子:

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

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

第二个例子:

varName: 是表示 <var></var> 的字符串在 <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())?

最佳答案

首先,您混淆了方法的 varName/baseName。实际的方法是:

Application#getResourceBundle()

varName: is the String representing the <resource-bundle><var> in faces-config.xml

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

ResourceBundle#getBundle()

baseName: is the fully qualified name of the resource bundle, like <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() ),而后者直接获取它。

至于技术和最终结果,没有区别。在这两种情况下,您将获得完全相同的 bundle (前提是语言环境正确)。但是,至于可维护性,它肯定是不同的。资源包属于“配置”,必须外部化(在 faces-config.xml 中)。

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


还有第三种方法:注入(inject)即可。

在 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() .

关于jsf - JSF 2.0 中 Application#getResourceBundle() 和 ResourceBundle#getBundle() 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27927717/

相关文章:

jsf - 用于 JSF 的服务器端 HTML sanitizer /清理

jsf - 警告 : JSF1074: Managed bean named 'bean' has already been registered

jsf-2 - Icesfaces vs Myfaces vs Primefaces

ios - 根据按需资源标签启用/禁用按钮

java - 在 jsf 标签内调用 if 函数两次

jsf-2 - JSF 2 : h:link and getrowdata

java - 如何使用 Primefaces 在 JSF 页面中显示来自 Java 缓冲区的消息

java - 如何从动态插入属性文件/资源​​包中的键值中的数字中删除逗号?

java - 在 OSGi bundle 中加载 ResourceBundle

ajax - JSF 2 — f :ajax 上具有可选监听器属性的复合组件