将Web Flow(2.3.1.RELEASE)与JSF结合使用时,在使用任何类型的复合组件时都存在渲染问题,例如单击<h:outputLabel />
后,单页上的<h:commandLink />
组件。复合组件的内容始终显示在页面底部!刷新页面时,渲染再次正常......
我可以使用以下代码轻松复制:
我的面孔:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:test="http://java.sun.com/jsf/composite/components">
<h:body>
<h:form id="form">
<h:commandLink id="link" value="link" /><br/>
<test:testComponent id="test" />
<h:outputLabel value="label" id="label" />
</h:form>
</h:body>
</html>
复合组件:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
</composite:interface>
<composite:implementation>
<h:outputText value="hello world" />
</composite:implementation>
</ui:composition>
我怀疑当Web Flow在恢复流后恢复视图时,组件的排序会搞乱。在简单的JSF facelet中使用上面的代码(不使用Web Flow)时,一切正常。
我已经通过Mojarra和Web Flow的内部进行了调试,并且可以看到在使用Web Flow时,在使用简单JSF时,在FaceletViewHandlingStrategy的buildView(FacesContext ctx,UIViewRoot视图)方法中混合了顺序。
我在Spring论坛和Spring JIRA上发布了同样的问题,但是没有得到很多答复。
我想提前感谢任何人看看这个问题!
答案 0 :(得分:0)
您是否尝试将此添加到MVC servlet上下文XML?
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" >
<webflow:flow-execution-attributes>
<webflow:redirect-in-same-state value="false"/>
</webflow:flow-execution-attributes>
....
</webflow:flow-executor>
答案 1 :(得分:0)
SpringSource团队解决了这个问题:
似乎这个问题的主要原因是com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.adjustIndexOfDynamicChildren()。添加条件断点(在UIForm的父实例上)显示子顺序的更改方式。 似乎com.sun.faces.context.StateContext通过SystemEventListener内部类跟踪动态更改。最初调用startTrackViewModifications时,侦听器将添加到UIViewRoot。收到第一个回发时使用的侦听器与重定向后使用的侦听器之间似乎不匹配: 收到回传 恢复JSF视图并启动startTrackViewModifications 事件已处理完毕 发布重定向 收到重定向GET JSF视图已恢复,但之前的StateContext $ AddRemoveListerner似乎已经附加 现在有两个StateContext正在运行,一个新的添加,前一个通过AddRemoveListerner引用 现在调用startTrackViewModifications只更新较新的StateContext 为了解决这个问题,我们需要确保在重定向之前调用StateContext.release()方法。此方法将在UIViewRoot上触发unsubscribeFromViewEvent。似乎StateContext.release()只通过StateManagerImpl.saveView调用。由于Spring Web Flow有自己的状态管理,因此目前并不总是调用此方法。
由Phil Webb提供