我有一个jsf 1.2应用程序,其代码如下:
<c:forEach items="#{test.customerList}" var="itm">
<h:panelGroup layout="block">
<h:panelGroup layout="block" style="float:left;">
<h:outputText value="#{itm.customerName}"/>
</h:panelGroup>
<h:panelGroup layout="block" style="float:right;">
<c:forEach items="#{itm.addressTypeList}" var="adrssType">
<h:graphicImage id="addressTypeIcon" url="/images/services/16x16#{adrssType.contactaddresstypeicon}" alt="#{adrssType.contactaddresstypedesc}" title="#{adrssType.contactaddresstypedesc}" style="margin-top:4px;margin-left:5px;" rendered="#{adrssType.contactaddresstypeid lt 6}"/>
</c:forEach>
</h:panelGroup>
</h:panelGroup>
</c:forEach>
我第二次搜索客户时遇到“javax.servlet.ServletException:组件的重复ID”异常。我把问题缩小到以下开头的行:
<h:graphicImage id="addressTypeIcon"
如果我删除这一行,我没有得到异常,但我也没有得到我想要显示的图像。会导致这种情况的原因是什么?
答案 0 :(得分:4)
JSTL标记在视图构建期间运行,即需要根据JSP / XHTML文件填充JSF组件树的那一刻。实际上,嵌套在<c:forEach>
内的所有JSF组件都会在JSF组件树中重复重新创建,因为它需要迭代多次。因此,当您使用类似<h:graphicImage>
中的硬编码ID时,它最终会在组件树中重复出现,从而导致此异常。
当您使用JSF组件迭代集合而不是JSTL标记处理程序(例如<h:dataTable>
,<ui:repeat>
,{{1>时,不会发生此“重复组件ID”错误然后在JSF组件树中只有一个 <t:dataList>
,然后在视图渲染时重复使用它来生成HTML输出,需要根据JSF组件树生成HTML输出的那一刻。因此,JSF会自动将迭代索引附加到生成的客户端ID,以便生成的HTML DOM树不会以重复的HTML元素ID结束。
如果除了<a4j:repeat>
之外没有其他选项,那么您应该自己将迭代索引附加到ID。 E.g:
<h:graphicImage>
或者,您也可以删除整个<c:forEach>
。然后,JSF将自动生成一个,从而确保唯一性。