0

将 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 view) 方法中的顺序混合在一起。

我已经在 Spring 论坛和 Spring JIRA 上发布了同样的问题,但没有很多回复。

我要提前感谢任何看到这个问题的人!

4

2 回答 2

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 有自己的状态管理,这个方法目前并不总是被调用。

菲尔·韦伯提供

于 2013-02-04T07:36:32.227 回答
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>
于 2013-01-16T19:14:01.577 回答