1

次の会話スコープのバッキング Bean があります。

@Named
@ConversationScoped
public class TestConversation implements Serializable {

    private Logger logger = LoggerFactory.getLogger(TestConversation.class);

    private List<Integer> numbers;

    @Inject
    private Conversation conversation;

    @PostConstruct
    public void init() {
        logger.info("Creating TestConversation bean!!!");

        numbers = new ArrayList<Integer>();
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);
        numbers.add(6);

        conversation.begin();        
    }

    public void commandLinkAction() {
        logger.info("Invoking commandLinkAction");
    }

    public List<Integer> getNumbers() {
        return numbers;
    }
}

そして、次の facelets ビュー:

<!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:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>Testing Conversation</title>        
    </h:head>

    <h:body>
        <h:form>
            <h:dataTable value="#{testConversation.numbers}" var="num">
                <h:column>                    
                    <h:outputText value="#{num}"/>
                </h:column>
                <h:column>                    
                    <h:commandLink action="#{testConversation.commandLinkAction}">Trigger form submission</h:commandLink>
                </h:column>
            </h:dataTable>
        </h:form>
    </h:body>
</html>

ページに入ると、INFO: Creating TestConversation bean!!!どちらが正しいかがわかります。

しかし、次に をクリックするh:commandLinkと、次のように表示されます。

情報: TestConversation Bean を作成しています!!!
情報: commandLinkAction を呼び出しています

Bean が再度作成されました。これは、会話が伝搬されなかったことを意味します。これは次のことと矛盾すると思います。

ドキュメントからの引用:

JSF ビューをレンダリングするリクエストに関連付けられた長時間の会話コンテキストは、そのレンダリングされたページから発生するすべての Faces リクエスト (JSF フォーム送信) に自動的に伝播されます。

これを追加すると<f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>、すべて正常に動作します。誤解がありますか?

PSなしでは、2回目f:paramにクリックすると正常に動作しますがcommandLink、初めては動作しません:(。

4

2 に答える 2

3

コンポーネントが処理されたときに会話が開始されなかった<h:form>ため、フォームのアクションにcidが初めて含まれていなかったようです..

2 回目は、リンクをクリックすると、testConversation.commandLinkActionにアクセスしてtestConversation、会話を処理する前に開始することができます。<h:form>

以下の変更を試してください

処理の前に会話が開始されるため、例の#{testConversation}前に配置すると正常に動作します<h:form><h:form>

お役に立てれば..

于 2012-01-06T12:01:13.177 に答える
2

前の回答に基づいて、フォームに自動的TestConversationに含めるには手遅れになるまでBeanが構築されていないためです。cid

この場合、ビューのデータを初期化しているので、代わりに preRenderView イベント リスナーに配置する方がよいでしょう。

<f:event type="preRenderView" listener="#{testConversation.init}"/>

これを facelet テンプレートの早い段階f:metadata( と組み合わせて使用​​されることが多いため) などに配置し、注釈f:viewParamを削除します。これにより、EL 式で参照されているため、構築中の Bean の副作用として実行されることに依存するのではなく、明示的な@PostConstruct呼び出しが行われます。init

于 2012-01-06T18:50:18.027 に答える