Difference between by Application#getResourceBundle() and ResourceBundle#getBundle() in JSF 2.0

天涯浪子 提交于 2019-12-04 04:46:20

问题


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:

First Example:

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

Second Example:

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

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()) ?


回答1:


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

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

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.

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

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.

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

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

Or in a CDI managed bean:

@Inject
private PropertyResourceBundle text;

With this producer:

public class BundleProducer {

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

}

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



来源:https://stackoverflow.com/questions/27927717/difference-between-by-applicationgetresourcebundle-and-resourcebundlegetbund

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!