重定向到相同的Webflow视图状态会导致嵌套复合的异常

时间:2013-09-05 09:50:10

标签: jsf redirect nested spring-webflow composite-component

考虑一个带有输入文本的简单页面,并对其进行一些验证。该页面作为视图状态包含在Spring Webflow中。在验证失败时,需要重新显示相同的视图状态,包括验证消息。这很好用。使用封装输入和消息的复合组件也可以正常工作。

但是,在另一个复合内使用相同的复合组件会导致以下错误:

FacesException: Cannot add the same component twice

此异常源于一个名为handleAddRemoveWithAutoPrune的方法,该方法将组件添加到动态操作列表中,并在第二次添加组件时抛出错误。

以下是重现行为的示例:

JSF Page

<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上运行

0 个答案:

没有答案