我正在实现一个JSF组件,需要有条件地添加一些属性。这个问题类似于之前的JSF: p:dataTable with f:attribute results in "argument type mismatch" error,但是有一个完全不同的错误信息,所以我提出了一个新问题。
<composite:interface>
<composite:attribute name="filter" required="false" default="false"
type="java.lang.Boolean"/>
<composite:attribute name="rows" required="false" default="15"
type="java.lang.Integer"/>
...
</composite:interface>
<composite:implementation>
<p:dataTable ivar="p" value="#{cc.attrs.dm}">
<c:if test="#{cc.attrs.filter}">
<f:attribute name="paginator" value="#{true}"/>
<f:attribute name="rows" value="#{cc.attrs.rows}"/>
</c:if>
...
<p:dataTable>
</composite:implementation>
这会导致错误java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
。即使我手动设置了这个,我也会收到错误:
<f:attribute name="rows" value="15"/> ... argument type mismatch
<f:attribute name="rows" value="#{15}"/> ... java.lang.Long cannot be cast
to java.lang.Integer
如果我直接添加属性,则没有异常,并且显示正确的行数:
<p:dataTable var="p" value="#{cc.attrs.dm}" rows="#{cc.attrs.rows}">
答案 0 :(得分:3)
对于EL和复合组件属性中的数字,这确实是一个不幸的极端情况。对此没有解决方案。在#{cc.attrs}
中使用时,<f:attribute>
中未提供类型信息,因此将其视为String
。 #{15}
也不能在EL中表示为整数,当缺少类型信息时,所有数字总是隐式地视为Long
。可以使用标记文件而不是复合组件来阻止ClassCastException
。
您最好的选择是检查实际的rows
属性本身。
<p:dataTable ... rows="#{cc.attrs.filter ? cc.attrs.rows : null}">