为什么JSF资源包var可以与f:loadBundle和faces-config使用不同的方式

时间:2013-06-19 20:36:52

标签: jsf-2 resourcebundle

我有一个属性文件链接两种方式(使用f:loadBundle和faces-config.xml)都有不同的var名称。所以看起来如下:

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"/>
在myPage.xhtml中的

我列出了属性文件中的所有键。我似乎无法理解的是,当我在下面的代码中使用#{prop}时,它可以工作,但当我用#{myProp}替换它时,列表不再显示。

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

我认为这意味着两种情况下的变量在幕后都不一样,但如果有人能以不同的方式解释(或指向我的解释),我将不胜感激。理想情况下,我只想使用#{myProp}而无需在代码中拉出密钥并将其存储在列表中。

感谢。

1 个答案:

答案 0 :(得分:3)

<f:loadBundle><resource-bundle>都是加载属性的不同方式,其差异在于其访问范围。顺便提一下,后者还有@ManagedProperty("#{myProp}")

所附带的额外好处injectable in a managed bean

在faces-config.xml中使用<resource-bundle>会创建一个 全局 资源包,可以在应用程序的任何位置访问该资源包。这是通过java.util.ResourceBundle实例实现的。

在视图中使用<f:loadBundle>会创建 视图特定的 资源包,该资源包只能在该视图中访问。标记处理程序使用Map的内部实现来实现它。这是VDL of the tag

中指定的
  

加载为当前视图的Locale本地化的资源包,   并在其请求属性中将其公开为 java.util.Map   当前请求在“var”的值指定的密钥下   此标记的属性。

现在,由于您尝试使用datatypes.properties到<f:selectItems>的值,因此您将获得所述异常。这是因为标记should evaluate to a Collection or an array属性。

  

指向任何集合数组的值表达式。会员   元素可以是SelectItem或任何Java对象的实例。

因此,为了使用全局包实例,首先必须在使用它之前将其转换为支持bean中的List<SelectItem>

注意:您可以通过在initializeItems(Object)课程的com.sun.faces.renderkit.SelectItemsIterator方法中设置断点来验证上述情况。当然,这是假设您正在使用Mojarra实现。