4

入力テキストといくつかの検証を含む単純なページを考えてみましょう。ページはビュー ステートとして Spring Webflow に含まれます。検証が失敗した場合、検証メッセージを含め、同じビュー ステートを再表示する必要があります。これはうまくいきます。入力とメッセージをカプセル化する複合コンポーネントを使用しても問題なく動作します。

ただし、別のコンポジット内で同じコンポジット コンポーネントを使用すると、次のエラーが発生します。

FacesException: Cannot add the same component twice

この例外は、handleAddRemoveWithAutoPruneと呼ばれるメソッドから発生します。このメソッドは、動的アクション リストにコンポーネントを追加し、コンポーネントが 2 回目に追加されることになっている場合にエラーをスローします。

動作を再現する例を次に示します。

JSFページ

<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>

(ビーンとフローの定義は省略。平易な標準的なもの)

私はこれをしばらく調べました。同様の問題を抱えている他の人は通常、反復コンポーネント (dataTable など) 内でコンポジットを使用するときにこの問題に遭遇します。そのため、コンポーネントはビューの作成時およびビューの復元時に動的に追加されます。その後、同じビューへのポストバックで問題が発生します。たとえば、このチケットはこちらを参照してください。そこでは、元の投稿者のエンコード方法の欠陥が原因でエラーが発生しましたが、私のコンポーネントはプレーンでシンプルで、背後にカスタム Java がないため、これは役に立ちません...

それにもかかわらず、2 つの回避策を見つけました。Spring Webflows のドキュメントで説明されているように、同じビュー状態への遷移が発生すると、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 キーを押したり、戻る/進むを使用したときに、クロムなどの一部のブラウザーでフォームの送信と通知が二重になるのを防ぐために望ましい動作です。

2) 本文にあるように、Ajax リクエストではリダイレクトが発生しないため<f:ajax execute="@form" render="@form" />、送信ボタンに追加することでも問題は解決します。しかし、完全なフォームの送信に本当に Ajax を使用したいのでしょうか? 私にはちょっと無意味に思えます。

これは今のところ機能しますが、1) 重大な欠点があり、2) 物事が少し複雑になり、常に望ましいとは限りません。したがって、私はむしろ元の問題を解決したいと思います(または、最初にそれを理解します)。また、これが基礎となる実装の問題である場合は、バグ レポートを提出することをお勧めします (まだレポートがない場合)。

編集: Mojarra 2.1.21、JSF 2.1、Spring Webflow 2.3.2 を使用した JBoss での実行

4

0 に答える 0