4

@ConversationScoped Bean があり、次のように開始メソッドがあります。

@PostConstruct
public void start() {
    if (conversation.isTransient()) {
        conversation.begin();
        log.debug("conversation.getId(): " + conversation.getId());
    }
}

私の問題は、ページが更新されるたびに新しい会話が開始され、Bean 内のメソッドへの AJAX 呼び出しがあるたびに新しい会話も開始されることです (これが私の主な問題です)。

私が本当にやりたいことは、手動で conversation.end() を呼び出すまで、sam 会話がぶらぶらすることです。ここで何が欠けていますか?

4

6 に答える 6

6

少しトピックから外れていますが、うまくいけば価値があります:

@PostConstruct が会話を始めるのに適切な場所であると 100% 確信できるわけではありません。次のような顔イベントを使用したいと思います。

<f:metadata>
        <f:event type="javax.faces.event.PreRenderViewEvent"
                listener="#{myBean.init}" />
</f:metadata>

JSF ポストバック要求ではないことが確実な場合は、会話を開始します。

public void init() {
       if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {
          conversation.begin();
       }
    }

Seam 3 を使用すると、さらに簡単になります。

<f:metadata>
   <s:viewAction action="#{myBean.init}" if="#{conversation.transient}" />
</f:metadata>
于 2011-05-30T07:24:24.343 に答える
4

(AJAX) 呼び出しに会話 ID パラメーター (cid) が含まれていることを確認しましたか?

それが欠落している場合、通話ごとに新しい会話が開始されることが期待されます。

于 2011-05-29T13:56:45.683 に答える
3

JSR-299 組み込み Conversation の概念は少し壊れています。少なくとも JSF アプリの場合。@PreRenderViewEvent を使用すると、すべての@ConversationScoped Bean が longRunningになるため、基本的にこのアプローチのすべての利点が失われます。

代わりに Apache MyFaces CODI @ConversationScoped を使用してみてください。CODI は、Apache OpenWebBeans と Weld でうまく動作することが知られている CDI 拡張ライブラリです。さらに、@ViewScoped、@ViewAccessScoped (一種の自動会話)、および @WindowScoped コンテキストも提供します。

詳細: https://cwiki.apache.org/confluence/display/EXTCDI/Index

于 2011-06-24T22:53:31.647 に答える
2

それはすべてドキュメントにあります:

会話スコープがアクティブです:

JSF フェースまたは非フェース リクエストのすべての標準ライフサイクル フェーズ中。

会話コンテキストは、特定の会話に関連付けられた状態へのアクセスを提供します。すべての JSF リクエストには、関連する会話があります。この関連付けは、次のルールに従ってコンテナーによって自動的に管理されます。

どの JSF リクエストにも、関連付けられた会話が 1 つだけあります。JSF リクエストに関連付けられた会話は、ビューの復元フェーズの開始時に決定され、リクエスト中に変更されません。

会話は、一時的または長時間実行の 2 つの状態のいずれかになります。

デフォルトでは、会話は一時的です 一時的な会話は、Conversation.begin() を呼び出すことによって長期実行としてマークされる場合があります。

すべての長時間実行会話には文字列値の一意の識別子があり、会話が長時間実行としてマークされたときにアプリケーションによって設定されるか、コンテナーによって生成されます。

現在の JSF 要求に関連付けられている会話が、JSF 要求の終了時に一時的な状態にある場合、その会話は破棄され、会話コンテキストも破棄されます。

現在の JSF 要求に関連付けられている会話が、JSF 要求の終了時に長期実行状態にある場合、それは破棄されません。代わりに、次のルールに従って他のリクエストに伝播される場合があります。

JSF ビューをレンダリングするリクエストに関連付けられた長時間の会話コンテキストは、そのレンダリングされたページから発生するすべての Faces リクエスト (JSF フォーム送信) に自動的に伝播されます。JSF リダイレクト (ナビゲーション ルールまたは JSF NavigationHandler に起因するリダイレクト) をもたらすリクエストに関連付けられた長期対話コンテキストは、結果の非 Faces リクエスト、および同じ URL への他の後続のリクエストに自動的に伝播されます。これは、会話の一意の識別子を含む cid という名前の GET 要求パラメーターを使用して実現されます。リクエストに関連付けられた長時間の会話は、会話の一意の識別子を含むcidという名前のGETリクエストパラメーターを使用して、faces以外のリクエストに伝播できます。この場合、

会話が JSF 要求に伝搬されない場合、その要求は新しい一時的な会話に関連付けられます。長時間実行される会話はすべて、特定の HTTP サーブレット セッションに限定され、セッションの境界を越えることはできません。次の場合、伝播された長時間の会話を復元して、要求に再度関連付けることはできません。

HTTP サーブレット セッションが無効になると、サーブレットの service() メソッドが完了した後、現在のセッション中に作成されたすべての長時間実行会話コンテキストが破棄されます。コンテナは、リソースを節約するために、現在の JSF リクエストに関連付けられていない長時間実行されている会話を任意に破棄することが許可されています。

著者:ギャビン・キング、ピート・ミューア

于 2011-05-30T07:20:11.113 に答える
0

私見 CDI の会話は意図的に中断されており、struberg 氏は有望な代替手段を指摘しています。私のアプリでも同じ問題があり、現在 CDI + CODI 1 にリファクタリングしていますが、ちょうどいい感じです。@ConversationScoped は、これらすべての問題を解決します。アプリをリファクタリングしているときに、@ViewAccessScoped を使用して多くの厄介なケースを解決できました。指摘してくれたストルバーグに感謝します!

于 2011-08-19T17:03:14.947 に答える
0

奇妙なことに、Facelet にイベント リスナーを追加すると、たとえ空のメソッドを呼び出しても、生成されたソースのフォーム アクションには「cid」パラメーターが含まれるため、AJAX 呼び出しは新しい会話を作成しません。イベントリスナーがないと、「cid」がフォームアクションにありません。

<f:metadata>
    <f:event listener="#{myBean.dummy}" type="preRenderView" />
</f:metadata>

MyBean.java

public void dummy() {}
于 2013-06-23T03:40:35.247 に答える