How can I get a message bundle string from inside a managed bean?
Asked Answered
A

3

32

I would like to be able to retrieve a string from a message bundle from inside a JSF 2 managed bean. This would be done in situations where the string is used as the summary or details parameter in a FacesMessage or as the message in a thrown exception.

I want to make sure that the managed bean loads the correct message bundle for the user's locale. It is not clear to me how to do this from a managed bean using JSF API calls.

My configuration is:

  • Using Tomcat 7 as the container so the solution cannot depend on API calls that only work in a full application server container
  • Using the JSF 2 reference implementation (Mojarra)
  • NOT using any libraries that allow CDI

NOTE: I did see this similar question, but it depends on features that are unavailable in my configuration

EDIT: I made a mistake in my original question. What I meant to ask was "How can I get a resource bundle string from inside a managed bean"? BalusC gave me the correct answer for what I asked. The solution for what I actually meant to ask is very similar:

public static String getResourceBundleString(
            String resourceBundleName,
            String resourceBundleKey)
        throws MissingResourceException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ResourceBundle bundle = 
        facesContext.getApplication().getResourceBundle(
            facesContext, resourceBundleName);
    return bundle.getString(resourceBundleKey);
}

Also, here is a link to another question that explains the difference between "message" bundles and "resource" bundles.

Anglaangle answered 8/6, 2011 at 0:8 Comment(0)
I
55

You can get the full qualified bundle name of <message-bundle> by Application#getMessageBundle(). You can get the current locale by UIViewRoot#getLocale(). You can get a ResourceBundle out of a full qualified bundle name and the locale by ResourceBundle#getBundle().

So, summarized:

FacesContext facesContext = FacesContext.getCurrentInstance();
String messageBundleName = facesContext.getApplication().getMessageBundle();
Locale locale = facesContext.getViewRoot().getLocale();
ResourceBundle bundle = ResourceBundle.getBundle(messageBundleName, locale);
// ...

Update: as per the mistake in the question, you actually want to get the bundle which is identified by the <base-name> of <resource-bundle>. This is unfortunately not directly available by a standard JSF API. You've either to hardcode the same base name in the code and substitute the messageBundleName in the above example with it, or to inject it as a managed property on <var> in a request scoped bean:

@ManagedProperty("#{msg}")
private ResourceBundle bundle; // +setter
Invisible answered 8/6, 2011 at 0:13 Comment(5)
I just tried this, but the messageBundleName is being set to null which causes a NullPointerException in the call to getBundle().Anglaangle
My mistake. I was confused about resource bundle vs message bundle. See my edit of the original question.Anglaangle
The latter solution doesn't work. It reports NullPointerException for bundle.Populace
@Emerald: Works for me and anyone else when following exactly the information provided in both the question and answer. Just press [Ask Question] button if you still can't figure out instead of polluting valid answers with misleading and uninformative "doesn't work" comments.Invisible
@Invisible this works for me only for message bundles in English and in German, but not in Bulgarian. Do you know why?Flawy
L
27
FacesContext context = FacesContext.getCurrentInstance();
ResourceBundle bundle = context.getApplication().getResourceBundle(context, "msg");
String message = bundle.getString("key");

here is key is property name which you want to access from properties file .

       message = This is "message"

This entry is from messages.properites file. and "message" is "key" .

Laurettalaurette answered 2/8, 2011 at 17:8 Comment(2)
Indeed this works like a charm. I do wonder though why you need to speficy the context as a paramater.Cochard
"msg" is the variable defined in faces configAnastos
S
6

There are two ways to get String resource bundle in managed bean, using baseName or varName (see definition of each one below):

Using varName:

varName: is the String representing the <var></var> in <resource-bundle>

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle bundle = app.getResourceBundle(context, varName);
String msg = bundle.getString("key");

Using baseName:

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

FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context .getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, loader);
String msg = bundle.getString("key");
Sudarium answered 10/2, 2015 at 14:4 Comment(2)
Incorrect. ResourceBundle#getBundle() takes base name as 1st argument. Perhaps you're confused because you gave them both the same value.Invisible
@Invisible I mixed up the varName and baseName in the code, but i corrected that, thanks for your noticeSudarium

© 2022 - 2024 — McMap. All rights reserved.