我有一个属性文件链接两种方式(使用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}
而无需在代码中拉出密钥并将其存储在列表中。
感谢。
答案 0 :(得分:3)
<f:loadBundle>
和<resource-bundle>
都是加载属性的不同方式,其差异在于其访问范围。顺便提一下,后者还有@ManagedProperty("#{myProp}")
在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实现。