【问题标题】:Order of rendering when using composite components with WebFlow将复合组件与 WebFlow 一起使用时的渲染顺序
【发布时间】:2013-02-04 15:36:32
【问题描述】:

将 Web Flow (2.3.1.RELEASE) 与 JSF 结合使用时,我在使用任何类型的复合组件时都会遇到渲染问题,例如单击<h:commandLink /> 后,1 页上的<h:outputLabel /> 组件。复合组件的内容始终显示在页面底部!刷新页面时,渲染又好了……

我可以很容易地用这段代码重现这个:

我的小脸:

<!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 上发布了同样的问题,但没有很多回复。

我要提前感谢任何研究这个问题的人!

【问题讨论】:

    标签: java spring spring-webflow composite-component


    【解决方案1】:

    您是否尝试将其添加到 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>
    

    【讨论】:

    • 很好的答案。现在我只需要看看这个解决方案的其他副作用是什么,但它确实通过了初始测试!所以非常感谢你:)
    • SWF 会中断 Primefaces 的部分呈现,除非将 redirect-in-same-state 设置为 false。 Spring 文档中对此设置有一个晦涩的参考,请参阅static.springsource.org/spring-webflow/docs/2.3.x/reference/…,但它没有提及有关部分渲染的任何内容。我正在使用 PF 和 SWF 开发 webapp,将其设置为“false”并且没有注意到任何副作用。很高兴它有帮助,祝你好运!
    • 好吧,在某些特定情况下,它似乎确实会呈现浏览器警告(例如,重新提交表单),但这并没有从解决方案中拿走任何东西。很好的发现!
    【解决方案2】:

    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

    【讨论】:

    • 这解释了原因。或许值得一提的是,这已在 Spring Web Flow 2.4.0 M1 版本中得到修复——至少根据 Spring Jira 而言。
    猜你喜欢
    • 2018-11-09
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 2012-09-13
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    相关资源
    最近更新 更多