使用id =“#{...}”会导致java.lang.IllegalArgumentException:不允许使用空id属性

时间:2011-07-30 17:31:05

标签: jsf el

我需要为JSF中的某些组件生成动态ID来解决我的问题。

看一下这个例子:

<h:outputText id="#{bean.id}" value="#{bean.value}" />

我的问题是我收到了这个错误:

java.lang.IllegalArgumentException: Empty id attribute is not allowed

当我查看生成的HTML输出时,组件的ID为空。这是怎么造成的,我该如何解决?

1 个答案:

答案 0 :(得分:18)

  

你是对的。我在数据表中使用它。

如果#{bean}表示var属性中声明的当前迭代对象,则会发生这种情况,如下所示:

<h:dataTable value="#{someBean.beans}" var="bean">
    <h:column>
        <h:outputText id="#{bean.id}" value="#{bean.value}" />

JSF组件的id(和binding)属性在视图构建期间进行评估,即需要组合JSF组件树的那一刻。但是,#{bean}仅在视图渲染时可用,即<h:dataTable>需要遍历所有对象并为每个对象生成HTML表行的那一刻。因此#{bean}在视图构建期间不可用,并且评估为null,最终将EL强制转换为空字符串。因此异常java.lang.IllegalArgumentException: Empty id attribute is not allowed

你基本上有3种选择:

  1. 使用视图构建时标记来迭代集合。您只需要自己编写所有HTML样板:

    <table>
        <c:forEach items="#{someBean.beans}" var="bean">
            <tr>
                <td>
                    <h:outputText id="#{bean.id}" value="#{bean.value}" />
    
  2. 使用纯HTML元素:

    <h:dataTable value="#{someBean.beans}" var="bean">
        <h:column>
            <span id="#{bean.id}">#{bean.value}</span>
    
  3. 不要设置动态ID,而是设置固定ID。 JSF将通过在表格的行索引前面添加它来确保HTML输出的唯一性:

    <h:dataTable value="#{someBean.beans}" var="bean">
        <h:column>
            <h:outputText id="id" value="#{bean.value}" />
    
  4. 另见: