JSF 2.0中Application#getResourceBundle()和ResourceBundle#getBundle()之间的区别 [英] Difference between by Application#getResourceBundle() and ResourceBundle#getBundle() in JSF 2.0

查看:155
本文介绍了JSF 2.0中Application#getResourceBundle()和ResourceBundle#getBundle()之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In order to retreive Strings from the resourse bundle, i am trying to compare the result from this two methods, below an example for the code:

第一个示例:

baseName:资源束的标准名称(<resource-bundle>中的<base-name>).

baseName: The fully qualified name of the resource bundle (<base-name> in <resource-bundle>).

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

第二个示例:

varName:是表示<resource-bundle>

varName: is the String representing the <var></var> in <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())?

What is the difference between these tow examples? if no difference, what would be the best practice to get ResourceBundle (to use Application#getMessageBundle() or ResourceBundle#getBundle()) ?

推荐答案

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

First of all, you mixed up the varName/baseName of the approaches. The actual approaches are:

Application#getResourceBundle()

varName:是表示faces-config.xml

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:是资源束的标准名称,例如<resource-bundle><base-name>

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()),而后者则是直接获得的.

The former obtains it via JSF Application, which would under the covers also use UIViewRoot#getLocale() (with a fallback to Locale#getDefault()), while the latter obtains it directly.

关于技术和最终结果,没有区别.在两种情况下,您都将获得完全相同的捆绑软件(前提是语言环境正确).但是,就可维护性而言,肯定是不同的.资源束属于配置",必须被外部化(在faces-config.xml中).

As to the technical and the end result, there's no difference. You'll get exactly the same bundle in both cases (provided that locale is right). However, as to maintainability, it's definitely different. Resource bundles fall under "configuration" and it must be externalized (in faces-config.xml).

baseName中那样对FQN进行硬编码是一种不良做法.您无法轻松地快速更改FQN,而无需重新编译并重新构建所有代码.如果它在第3方JAR文件中,那就更麻烦了.否则,您可以在Webapp内部使用同一<var>上的另一个<resource-bundle>覆盖它.同样,JSF组件/实用程序库可能提供自己的Application包装器,该包装器可能会修饰getResourceBundle()调用以便进行一些令人敬畏的工作.如果您直接通过ResourceBundle#getBundle()获得它,那将是不可能的.

Hardcoding a FQN as in baseName is a poor practice. You can't easily quickly change the FQN without recompiling and rebuilding all the code again. If it was in a 3rd party JAR file, it would be even more troublesome. You could otherwise just override it with another <resource-bundle> on same <var> from inside your webapp. Also, JSF component/utility libraries may provide an own Application wrapper which could possibly decorate getResourceBundle() call in order to do some awesomeness. That wouldn't be possible if you obtained it directly via ResourceBundle#getBundle().

还有第三种方法:注入它.

There's by the way a third approach: just inject it.

在JSF托管bean中,提供了<var>text</var>:

In a JSF managed bean, provided a <var>text</var>:

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

或在CDI托管bean中:

Or in a CDI managed 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()的封面下使用.

Note: EL evaluation of #{text} bundle uses under the covers Application#getResourceBundle().

这篇关于JSF 2.0中Application#getResourceBundle()和ResourceBundle#getBundle()之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆