考虑一个带有输入文本的简单页面,并对其进行一些验证。该页面作为视图状态包含在Spring Webflow中。在验证失败时,需要重新显示相同的视图状态,包括验证消息。这很好用。使用封装输入和消息的复合组件也可以正常工作。
但是,在另一个复合内使用相同的复合组件会导致以下错误:
FacesException: Cannot add the same component twice
此异常源于一个名为handleAddRemoveWithAutoPrune的方法,该方法将组件添加到动态操作列表中,并在第二次添加组件时抛出错误。
以下是重现行为的示例:
<h:form id="form">
<h:inputText id="text" value="#{bean.someValue}" >
<f:validateLength maximum="3" />
</h:inputText>
<h:message for="text" />
<!-- This will work -->
<test:ccInner anything="Blubb" />
<!-- This will not work -->
<test:ccOuter id="outer" title="Outer Component">
<test:ccInner id="inner" anything="Inner Component" />
</test:ccOuter>
<h:commandButton id="button" type="submit" value="Submit"
action="#{bean.doStuff}" />
</h:form>
内
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<cc:interface>
<cc:attribute name="anything" />
</cc:interface>
<cc:implementation>
#{cc.attrs.anything}
</cc:implementation>
</html>
外
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<cc:interface>
<cc:attribute name="title" />
</cc:interface>
<cc:implementation>
#{cc.attrs.title}
<cc:insertChildren />
</cc:implementation>
</html>
(省略bean和流程定义。简单标准的东西)
我看了一会儿。其他有类似问题的人在迭代组件(例如dataTable)中使用复合时通常会遇到它,因此组件将在视图创建和视图恢复时动态添加。然后问题发生在同一视图的回发上,例如参见this ticket here。在那里,错误是由原始海报的编码方法中的缺陷引起的,但是,我的组件简单明了,没有自定义Java,所以这对我没有帮助......
尽管如此,我发现了两种解决方法:如所描述的in the Spring Webflows documentation,当流向相同视图状态的转换发生时,Webflow会自动执行重定向。
1)通过添加
关闭此行为<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-attributes>
<webflow:redirect-in-same-state value="false"/>
</webflow:flow-execution-attributes>
</webflow:flow-executor>
到webflow.xml
问题消失了。但是,正如文本所建议的那样,原始重定向是一种理想的行为,可以防止在某些浏览器中提交双重表单和通知,例如在击中F5或使用后退/前进时使用chrome。
2)正如文中所述,Ajax请求不会导致重定向,因此将<f:ajax execute="@form" render="@form" />
添加到提交按钮也可以解决问题。但我真的想使用Ajax提交完整表单吗?这对我来说似乎有些荒谬。
虽然目前有效,1)有严重的缺点,2)使事情变得复杂,也可能并不总是令人满意。因此,我宁愿解决原始问题(或者首先要了解它)。此外,如果这是底层实现中的问题,那么提交错误报告(如果没有错误报告)可能会很好。
编辑:使用Mojarra 2.1.21,JSF 2.1,Spring Webflow 2.3.2在JBoss上运行