我有一个属性文件链接两种方式(使用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"/>
在myppage .xhtml中的中,我列出了属性文件中的所有键。我似乎无法理解的是,当我在下面的代码中使用#{prop}
时,它可以工作,但是当我用#{myProp}
替换它时,列表不再显示。
<h:form>
<h:selectManyListbox id="list">
<f:selectItems value="#{myProp}"></f:selectItems>
</h:selectManyListbox>
</h:form>
我认为这意味着这两种情况下的变量在幕后是不一样的,但如果有人能解释(或指出一个解释)它们在什么方面不同,我会很感激。理想情况下,我想只是使用#{myProp}
,而不必在代码中拔出键并将它们存储在列表中。
谢谢。
<f:loadBundle>
和<resource-bundle>
都是加载属性的不同方式,不同的是它们的访问范围。顺便说一下,后者还有一个额外的好处,即bundle也可以通过@ManagedProperty("#{myProp}")
在faces-config.xml中使用<resource-bundle>
创建一个全局资源包,可以在应用程序的任何地方访问。这是通过java.util.ResourceBundle
实例实现的。
在视图中使用<f:loadBundle>
创建一个特定于视图的资源束,该资源束只能在该视图中访问。标记处理程序使用Map的内部实现来实现这一点。这在标记的VDL中指定:
加载一个为当前视图的Locale本地化的资源束,并将其公开为java.util。对象的请求属性中映射由"var"值指定的键下的当前请求属性。
现在,由于您正在尝试使用数据类型中的值。属性通过<f:selectItems>
,您将得到上述异常。这是因为标签的value属性应该计算为一个集合或数组。
指向任意集合或数组的值表达式。会员元素可以是SelectItem或任何Java Object的实例。
因此,为了使用全局bundle实例,您首先必须在使用它之前将其转换为支持bean中的List<SelectItem>
。
注意:您可以通过在com.sun.faces.renderkit.SelectItemsIterator
类的initializeItems(Object)
方法中设置一个断点来验证上述情况。当然,这是假设您使用的是Mojarra实现。