JSF Facelets Form嵌套的问题 The form action element can

本文描述了在使用Facelets过程中遇到的表单嵌套问题及其解决方案。作者最初遭遇了一个错误,提示表单元素不能嵌套。通过仔细检查发现了一个内部表单被错误地嵌套在另一个表单中,调整后问题得以解决。

一个javax.faces.FacesException: Problem in renderResponse: Nested form found on the page. The form action element can not be nested错误,又是找遍各大搜索引擎都没见结果,还是在ICEFaces的论坛里面有人提了这个问题,然后回答竟然是facelets的一个bug,并且ICEFaces的新版本会在自己的facelets实现里面修改这个补丁。

碰巧了,ICEFaces在20080414出了新版本,我遇到这个问题的同天……

下了新版本,简单看了下说明,更新到项目里面,运行,好了……

还没有结束……

 

 

解决了问题,休息会,喝杯茶,回来,运行,问题再现,一模一样,郁闷致死啊。

找了半天尝试了各种情况,未见结果。于是放弃两天的工作,重新换方法写。写到今天,20080416,直到出现一个情况,我点了页面上的不相干的链接,竟然造成一个不相干的表单的提交……Form出问题了

找啊找,在facelets一个页面n个insert、include、define等等的情况下,找到有一个Form嵌套在另外一个顶层template的Form里面了,调整了下,ok,问题解决……

 

哎,上面这么多,我自己都觉得太唐僧了点。谁让我又解决了一个问题高兴呢。虽然是非常郁闷的问题。

 

用facelets是方便了,但是一定要事先设计好,到做的时候临场发挥是最容易出问题的。灵活方便不见得是好事……

报错Message:Error Parsing //data/wls/config/domains/domain03/servers/MS1/stage/LkmPmi/LkmPmi.ear/LkmPmi.war/WEB-INF/lib/EventDataReportJsf.jar!/META-INF/resources/zhuanxu/zhuanxureport.jsf: Error Traced[line: 172] The element type "ui:define" must be terminated by the matching end-tag "</ui:define>".javax.faces.view.facelets.FaceletException: Error Parsing //data/wls/config/domains/domain03/servers/MS1/stage/LkmPmi/LkmPmi.ear/LkmPmi.war/WEB-INF/lib/EventDataReportJsf.jar!/META-INF/resources/zhuanxu/zhuanxureport.jsf: Error Traced[line: 172] The element type "ui:define" must be terminated by the matching end-tag "</ui:define>".,<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/LkmTemplate.jsf"> <ui:param name="pageTitle" value="转序效率分析"/> <ui:define name="head"> <h:outputScript name="js/highchart3.6/event-highcharts.js" target="body"/> <h:outputScript name="js/event-exporting.js" target="body"/> </ui:define> <ui:define name="content-introduction"> <h1>转序效率分析</h1> </ui:define> <ui:define name="content"> <div class="ui-fluid"> <div id="contentId"> <p:panel style="display: -webkit-inline-flex"> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon" style="width:55px;">类型</span> <p:selectOneMenu id="eventType" value="#{zhuanXuReportBean.eventType}" style="width:110px;" panelStyle="width:180px;"> <f:selectItem itemLabel="选择类型" itemValue=""/> <f:selectItems value="#{zhuanXuReportBean.typeList}"/> </p:selectOneMenu> </div> <p:spacer width="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon" style="width:55px">组织</span> <p:selectOneMenu id="org" value="#{zhuanXuReportBean.org}" style="width:80px"> <f:selectItem itemLabel="组织" itemValue=""/> <f:selectItem itemLabel="河源" itemValue="河源"/> <f:selectItem itemLabel="杭州" itemValue="杭州"/> </p:selectOneMenu> </div> <p:spacer width="5px" height="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon">统计始 </span> <p:calendar id="startDate" pattern="yyyy-MM-dd" value="#{zhuanXuReportBean.startDate}" inputStyle="width:90px"></p:calendar> </div> <p:spacer width="5px" height="10px"/> <div class="ui-inputgroup" style="display:inline-block;"> <span class="ui-inputgroup-addon">统计止 </span> <p:calendar id="endDate" pattern="yyyy-MM-dd" value="#{zhuanXuReportBean.endDate}" inputStyle="width:90px"></p:calendar> </div> <p:spacer width="5px" height="10px"/> <h:commandButton id="searchBtn" class="searchBtn" actionListener="#{zhuanXuReportBean.doSearch}" oncomplete="updateChart()" icon="fa fa-search" value="查询" update="dataTableId" style="width:80px;height:33px;background-color:#007ad9;border: 1px solid #007ad9;color: #ffffff;"/> </p:panel> </div> </div> <div> <p:dataTable id="dataTableId" widgetVar="dataTableId" emptyMessage="没有找到相关记录" value="#{zhuanXuReportBean.lazyEventDataList}" var="zx" styleClass="data-table centered-table fixed-layout-table" paginator="true" rows="6" paginatorPosition="bottom" rowsPerPageTemplate="5,10,20" lazy="true" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"> <!-- ID列 --> <p:column headerText="姓名" style="text-align:center;width:40px"> <h:outputText value="#{zx.name}" styleClass="ellipsis-text"/> </p:column> <!-- 名称列 --> <p:column headerText="工号" style="text-align:center;width:50px"> <h:outputText value="#{zx.empNo}" styleClass="ellipsis-text"/> </p:column> <!-- 地址列 --> <p:column headerText="时间跨度" style="text-align:center;width:130px "> <h:outputText value="#{zx.searchDate}" styleClass="ellipsis-text"/> </p:column> <!-- 创建时间列 --> <p:column headerText="转序数量" style="text-align:center;width:130px"> <p:column headerText="正常" style="text-align:center;width:60px"> <h:outputText value="#{zx.normalTimeNum}" styleClass="ellipsis-text"/> </p:column> <p:column headerText="超时" style="text-align:center;width:60px"> <h:outputText value="#{zx.overTimeNum}" styleClass="ellipsis-text"/> </p:column> </p:column> <!-- 备注列 --> <p:column headerText="操作" style="text-align:center;width:60px"> <p:commandLink update="@form:createDept" value="查看明细" action="#{zx.openEventDataDialog(zx)}" styleClass="centered-link"/> </p:column> </p:dataTable> </div> <div id="chartData" class="chartData" style="height:400px;"></div> <h:outputScript> document.addEventListener('DOMContentLoaded', function () { var chart1; var categories = #{zhuanXuReportBean.categoriesStr}; var salesData = #{zhuanXuReportBean.salesDataStr}; var eventType = '#{zhuanXuReportBean.eventType!=""?zhuanXuReportBean.eventType:"转序效率"}'; chart1 = new Highcharts.Chart({ chart: { renderTo: 'chartData', type: 'column' }, title: { text: eventType+'分析(件数)', x: -20 //center }, xAxis: { categories: eval(categories) }, yAxis: { title: { text: eventType+'分析(件数)', }, min: 0, plotLines: [{ value: 0, width: 1, color: '#808080' }] }, tooltip: { crosshairs: true, valueSuffix: '', shared: true }, plotOptions: { column: { pointPadding: 0.2, borderWidth: 0 } }, series: eval(salesData) }); // 更新图表数据 function updateChart() { var newCategories = #{engWojiaBean.categoriesStr}; var salesData = #{engWojiaBean.salesDataStr}; chart1.xAxis[0].setCategories(newCategories); chart1.series[0].setData(salesData); var series = chart1.series; series[1].hide(); series[2].hide(); series[5].hide(); } }); </h:outputScript> </div> </ui:define> </ui:composition>
08-20
<think>根据报错信息,错误发生在解析一个名为`zhuanxureport.jsf`的Facelets视图文件时。具体错误是: `The element type "ui:define" must be terminated by the matching end-tag "</ui:define>".` 这意味着在文件中有一个`<ui:define>`标签没有被正确关闭,即缺少了对应的结束标签`</ui:define>`。 观察提供的代码片段,我们可以看到有多个`<ui:define>`标签,但是最后一个`<ui:define name="content">`的结束标签在哪里? 在代码中,我们找到了一个`</ui:define>`,但是请注意,在最后一个`<ui:define>`标签内部,我们看到了一个`<div>`标签,它包含了多个子元素,然后最后有一个`</div>`,但是紧接着又有一个`<div id="chartData">`,然后是一个`<h:outputScript>`,然后是两个`</div>`,最后是`</ui:define>`。 然而,请注意代码结构: 1. `<ui:define name="content">` 开始 2. 然后是两个`<div>`(class="ui-fluid" 和 id="contentId" 的div,以及一个没有class的div) 3. 然后是一个`<div id="chartData">`(注意:这个div是在第二个div结束之后?) 4. 然后是`<h:outputScript>` 5. 然后是两个`</div>`(注意:这里有两个闭合div,但是它们分别对应哪个div?) 6. 最后是`</ui:define>` 问题可能出现在div的嵌套上。在第二个div(即包含`<p:dataTable>`的div)之后,我们直接开始了另一个div(id="chartData"),然后后面有两个闭合div。但是,我们并没有看到与id="chartData"的div对应的起始标签之前有未闭合的div?实际上,在代码中,第一个div(class="ui-fluid")在内部已经闭合了吗? 让我们重新梳理一下: - 第一个div: `<div class="ui-fluid">` 在内部有一个`<div id="contentId">`,然后这个`<div id="contentId">`在`<p:panel>`结束后闭合(注意:在`<p:panel>`结束后有一个`</div>`,它闭合了id="contentId"的div)。然后这个div(class="ui-fluid")在内部内容结束后也有一个`</div>`(在第一个`</div>`后面,紧接着有一个`</div>`,它闭合了class="ui-fluid"的div)。所以第一个div已经闭合。 - 然后是一个新的div:`<div>`(没有指定id或class),它包含一个`<p:dataTable>`,然后这个div在`</p:dataTable>`后没有立即闭合,而是继续包含了一个`<div id="chartData">`和一个`<h:outputScript>`。最后,我们看到了两个`</div>`。这里可能出现了问题。 实际上,在第二个div(即没有class的div)中,我们只看到了一个开始标签`<div>`,然后里面包含了`<p:dataTable>`和`<div id="chartData">`以及`<h:outputScript>`,然后连续两个`</div>`。这意味着第一个`</div>`闭合了id="chartData"的div(但是注意,id="chartData"的div并没有被嵌套在第二个div内?实际上,代码结构是: ``` <div> <!-- 第二个div开始 --> <p:dataTable> ... </p:dataTable> <div id="chartData"> ... </div> <!-- 这个div是第二个div的子元素 --> <h:outputScript> ... </h:outputScript> </div> <!-- 这里应该只有一个闭合div,因为只有一个div开始 --> ``` 但是代码中却有两个`</div>`,多了一个。所以,可能是多了一个闭合标签。 然而,我们再看一下代码的最后部分: ``` </div> <!-- 这个div应该是闭合上面的第二个div(没有class的div) --> </div> <!-- 这个div是多余的,因为它前面并没有对应的开始标签 --> ... 然后还有 </ui:define> ``` 所以,错误的原因可能是多了一个`</div>`,导致解析器在遇到`</ui:define>`之前已经认为标签结构错误,或者导致`<ui:define>`标签没有被正确闭合。 具体修正: 1. 删除多余的`</div>`标签。在代码中,我们看到在`<h:outputScript>`标签后面有两个`</div>`,我们只需要一个。删除其中一个。 2. 另外,我们还需要检查其他标签是否匹配。例如,`<p:column>`标签是否正确闭合?在JSF中,PrimeFaces的组件标签需要正确嵌套和闭合。 但是,根据错误信息,问题明确是`<ui:define>`标签没有被正确终止,所以我们应该关注`<ui:define name="content">`和`</ui:define>`之间的内容。 在提供的代码中,最后一个`<ui:define>`(name="content")内部的结构如下: ``` <ui:define name="content"> <div class="ui-fluid"> ... </div> <!-- 这个div已经正确闭合 --> <div> <!-- 开始第二个div --> <p:dataTable> ... </p:dataTable> <div id="chartData"> ... </div> <h:outputScript> ... </h:outputScript> </div> <!-- 这里只需要一个闭合div --> <!-- 注意:这里多了一个</div>,所以应该删除一个 --> </ui:define> ``` 所以,在代码的最后,我们看到有两个`</div>`,而实际上我们只需要一个(因为第二个div只有一个开始标签)。因此,删除一个`</div>`。 修改后的代码在`<h:outputScript>`后面应该只有一个`</div>`,然后紧接着是`</ui:define>`。 修改前: </div> <!-- 第一个多余的闭合div --> </div> <!-- 第二个闭合div,这个才是需要的? --> 修改后:删除一个`</div>`,只保留一个。 因此,将: ``` </h:outputScript> </div> <!-- 删除这个多余的 --> </div> </ui:define> ``` 改为: ``` </h:outputScript> </div> <!-- 只保留一个闭合div,这个div闭合了第二个div(没有class的div) --> </ui:define> ``` 但是,请注意:在`<h:outputScript>`标签之前,我们有一个`<div id="chartData">`,这个div在`<h:outputScript>`之前已经闭合了吗?在代码中,`<div id="chartData">`是一个独立的div,它没有包含`<h:outputScript>`,所以它应该在自己内部闭合?实际上,它没有内容,所以是自闭合的吗?不,在代码中,它是这样写的: ``` <div id="chartData" class="chartData" style="height:400px;"></div> ``` 所以这个div是自闭合的(虽然使用了`</div>`,但内容为空)。所以它不需要额外的闭合标签。 因此,在`<div id="chartData">`之后,我们只有`<h:outputScript>`,然后两个`</div>`。所以,第一个`</div>`闭合了包裹`<p:dataTable>`和`<div id="chartData">`以及`<h:outputScript>`的那个div(第二个div),而第二个`</div>`就是多余的。 所以,删除一个`</div>`即可。 另外,在`<p:dataTable>`内部,我们注意到有一个`<p:column>`嵌套了另外两个`<p:column>`,这是不允许的。`<p:column>`必须是`<p:dataTable>`的直接子元素,不能嵌套。所以这里也需要修正。 修正方法:将嵌套的`<p:column>`提升到与外部`<p:column>`同级,或者重新设计表格结构。但是根据错误信息,当前主要问题是`<ui:define>`标签未正确闭合,所以先解决主要问题。 总结修改步骤: 1. 删除多余的`</div>`标签(在`<h:outputScript>`后面,两个`</div>`删掉一个)。 2. 检查并修正`<p:dataTable>`中的列嵌套问题(这可能是另一个潜在错误,但当前报错不是这个)。 修改后的代码片段(只展示修改部分):</think>根据报错信息,问题出在 JSF 文件中的 XML 标签未正确闭合。具体错误是:`<ui:define>` 标签缺少对应的结束标签 `</ui:define>`。分析代码后发现,在 `</ui:composition>` 前确实缺少一个 `</ui:define>` 的闭合标签。 ### 问题原因 在以下代码结构中: ```xml <ui:define name="content"> <!-- 大量内容 --> </div> <!-- 多余的 div 闭合标签 --> </ui:define> <!-- 实际缺失这个闭合标签 --> </ui:composition> ``` 错误在于: 1. 在 `</ui:define>` 前多了一个 `</div>` 闭合标签 2. 缺少 `</ui:define>` 的闭合标签 ### 修复方案 需要做两处修改: 1. 删除多余的 `</div>` 标签 2. 在 `</ui:composition>` 前添加缺失的 `</ui:define>` 修正后的代码结尾部分: ```xml </h:outputScript> </div> <!-- 删除这个多余的 div 闭合标签 --> </ui:define> <!-- 添加缺失的 ui:define 闭合标签 --> </ui:composition> ``` ### 完整修复代码 ```xml <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/LkmTemplate.jsf"> <!-- ... 其他内容保持不变 ... --> <ui:define name="content"> <!-- ... 内容区域 ... --> <div id="chartData" class="chartData" style="height:400px;"></div> <h:outputScript> // JavaScript 代码 </h:outputScript> </ui:define> <!-- 修复位置:添加正确的闭合标签 --> </ui:composition> ``` ### 额外建议 1. **XML 格式验证**:建议使用 IDE 的 XML 验证功能(如 Eclipse 或 IntelliJ 的 XML 校验) 2. **标签缩进**:保持规范的缩进可帮助识别标签嵌套问题 3. **Facelets 调试**:在 `web.xml` 中启用开发模式: ```xml <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> ``` ### 常见 XML 错误预防 1. 始终确保每个开始标签都有对应的结束标签 2. 使用支持 JSF 的 IDE(如 Eclipse with JBoss Tools) 3. 定期运行 XML 验证(在 Eclipse 中:右键文件 > Validate)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值