0

Web Flow(2.3.1.RELEASE)をJSFと組み合わせて使用​​する場合、任意の種類の複合コンポーネント(たとえば、<h:outputLabel />をクリックした後の1ページのコンポーネント)を使用すると、レンダリングの問題が発生します<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がフローを再開した後にビューを復元すると、コンポーネントの順序が乱れるのではないかと思います。上記のコードを(Web Flowを使用せずに)単純なJSFフェイスレットで使用すると、すべて正常に機能します。

MojarraとWebFlowの内部をデバッグしたところ、プレーンJSFを使用しているときではなく、Web Flowを使用しているときに、FaceletViewHandlingStrategyのbuildView(FacesContext ctx、UIViewRoot view)メソッドで順序が混在していることがわかります。

これとまったく同じ問題をSpringフォーラムとSpringJIRAに投稿しましたが、多くの返信はありませんでした。

この問題を見てくださった方、よろしくお願いします!

4

2 に答える 2

0

これをMVCサーブレットコンテキスト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 に答える
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はすでに接続されているように見えますが追加され、AddRemoveListernerを介して参照される以前のバージョンがstartTrackViewModificationsを呼び出すと、新しいStateContextのみが更新されるようになりました。この問題を修正するには、リダイレクトの前にStateContext.release()メソッドが呼び出されるようにする必要があります。このメソッドは、UIViewRootでunsubscribeFromViewEventをトリガーします。StateContext.release()は、StateManagerImpl.saveViewを介してのみ呼び出されるようです。Spring Web Flowには独自の状態管理があるため、現在、このメソッドが常に呼び出されるとは限りません。

PhilWebb提供

于 2013-02-04T07:36:32.227 に答える