Why can JSF resource bundle var be used differently with f:loadBundle and faces-config

StackOverflow https://stackoverflow.com/questions/17200836

  •  01-06-2022
  •  | 
  •  

Pregunta

I have one property file linked both ways (using f:loadBundle and faces-config.xml) both with different var names. So it would look like the following:

datatypes.properties:

A=first
B=second
C=third

faces-config.xml:

<resource-bundle>
    <base-name>datatypes</base-name>
    <var>myProp</var>
</resource-bundle>

myPage.xhtml:

<f:loadBundle basename="datatypes" var="prop"/>

in myPage.xhtml I make a list of all the keys from the property file. What I can't seem to understand is that when I use #{prop} in the code below it works but when I replace it with #{myProp} the list no longer displays.

<h:form>
 <h:selectManyListbox id="list">
 <f:selectItems value="#{myProp}"></f:selectItems>
 </h:selectManyListbox>
</h:form>

I figure this means the variables in both cases are not the same behind the scenes but I would appreciate it if someone could explain (or point me to an explaination) in what way they are different. I would ideally like to just use #{myProp} without having to pull the keys out in code and store them in a list.

Thanks.

¿Fue útil?

Solución

Both <f:loadBundle> and <resource-bundle> are different ways to load properties with difference being in their access scopes. The latter has by the way the additional benefit that the bundle is also injectable in a managed bean by @ManagedProperty("#{myProp}")

Using <resource-bundle> in faces-config.xml creates a global resource bundle which can be accessed anywhere in your application. This is implemented through a java.util.ResourceBundle instance.

Using <f:loadBundle> in your view creates a view-specific resource bundle which is accessible only within that view. The tag handler implements this using an internal implementation of a Map. This is as specified in the VDL of the tag:

Load a resource bundle localized for the Locale of the current view, and expose it as a java.util.Map in the request attributes of the current request under the key specified by the value of the "var" attribute of this tag.

Now since you're trying to use the values from datatypes.properties through <f:selectItems>, you'll get the said exception. This is because the value attribute for the tag should evaluate to a Collection or an array.

Value expression pointing at any Collection or array. The member elements may be instances of SelectItem or any Java Object.

So in order to use the global bundle instance, you first have to convert the same into a List<SelectItem> inside your backing bean before using it.

NOTE: You can verify the above cases by setting a breakpoint in the initializeItems(Object) method in the com.sun.faces.renderkit.SelectItemsIterator class. This is, of course, assuming that you're using the Mojarra implementation.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top