2012-12-03 24 views
13

jsfプロジェクトのページを移動中にBusyConversationExceptionが発生しました。これは主に、ユーザーがajax呼び出し中に別のページに移動しようとした場合に発生します。これは、ユーザーがページの読み込みを待たずに別のリンクをクリックした直後にリンクをクリックした場合にも発生します。jsfでBusyConversationExceptionを回避する方法

たとえば、次のようなコードで生成された複数のリンクをユーザーがクリックした場合は、この例外が発生します。もう1つの例は、ユーザーがテキストフィールドにクエリを入力し、アプリケーションがこのクエリを検索するためのajax呼び出しを行うことです。そのクエリ中に、ユーザがあるボタンをクリックして別のページに移動すると、BusyConversationExceptionも発生します。

<h:commandLink value="#{theProfile.profileName}" 
       title="#{theProfile.profileName}" 
       action="#{profileBean.aProfileSelected}"> 
       <f:setPropertyActionListener target="#{currentProfileWebBean.theProfile}" value="#{theProfile}"/> 
</h:commandLink> 

私はExceptionHandlerWrapperクラスを拡張exceptionHandlerのクラスで例外のこのタイプをキャッチすることができますが、私は私の現在の状態を保存することはできませんし、私はこのような場合のためにできる最善のは、この例外が発生すると、メインページにリダイレクトすることです。

これを回避する解決策はありますか?回答とコメントに感謝します。

+0

注: 'BusyConversationException'はJSFの一部ではありません。私はCDIタグを追加しました。 – BalusC

+0

複数のConversation.beginコールが発生していますか? – LightGuard

+1

私もこの問題を抱えています。もし安心すれば、(Web検索に基づいて)_few_人がそれを持っているように見えるのに驚いています。会話スコープのBeanを削除し、セッションスコープとビュースコープ(Seam Facesが提供するCDIビュースコープを使用)を使用することができます。 – Nick

答えて

2

他の回答で述べたように、AJAXリクエストがまだ処理されているかどうか、AJAXイベントが前に提出するcommandLinkの実際のクリックにトリガされた場合、これは起こりますまたはcommandButton(入力フィールドのchangeイベントなど)

TherforeそれはAJAXイベントが伝播によるトリガされていないので、onclick="preventEventPropagation(event)";でBusyConversationExceptionsを避けるためにことはできません。

保留中のajaxイベントが完了するまで、実行中のajaxリクエストをリッスンし、サブミットをブロックすることで、問題を簡単に回避できます。

この問題と解決策については、このブログ記事JSF2 AJAX/Submit conversation issueで詳しく説明しています。

-1

私はこれを時折見てきました。私はそれが会話へのアクセスを直列にいくつかの努力をすることをお勧めだと思うし始めている:あなたがターゲットビューのためにその会話のインスタンスを必要としないときの会話ID(CID)を伝播する

  1. 避けます。具体的には、無関係なナビゲーションリンク/ボタンはcidパラメータを抑制する必要があります(正確に行う方法は考えていません)
  2. アクティブな会話を使用するリクエストを開始するときは、会話を伝播し、アクセス。 PrimeFacesまたは(さらに優れた)PrimeFaces ExtensionsのblockUIコンポーネントは、PrimeFaces p:ajaxStatusとともにビジー状態を示すとともに、半透明のオーバーレイとしても機能します。
  3. 可能な限り遅く会話を開始してください。これにより、長期的な会話が伝播するケースが最小限に抑えられます。

私はこれが完全な解決策だとは思わないが、 cidがロケーションバーで終了すると(会話がアクティブなときにフォームのバック以外のポストバックを行うと起こる)、複数のタブ/タブのためにその会話へのアクセスのタイミングを制御できなくなる可能性があります。窓、ブックマークなど

+0

私たちの場合は、会話を終了して新しい会話を開始するときに問題があります。ユーザーがh:commandLinkをクリックするたびに新しい会話を開始するにはどうすればよいですか?私はセッター#{currentProfileWebBean.theProfile}を介してバッキングbeanの会話を終了しようとしましたが、cidがまったく変更されていないことがわかりました。そして、postConstructsは再び呼び出されませんか?だから私は会話が正しく終了していないと思う、あなたはそれについて何か考えている? – cubbuk

+0

ここでは、cidが 'h:commandLink'から送信されないようにしたいと思っています(もう一度やり方を考えなかったし、' h:link'の代わりに 'h:link'を使う必要があるかもしれません) commandLink')。そうすれば、リクエストに対するアクティブな会話はなくなり、新しいものを自由に開始することができます。このテクニックは、会話を終了するのではなく、会話を残すことと考えることができます。 – Brian

+0

私は、h:commandLinkを使っていくつかのパラメータを投稿していますが、新しい会話が新しいページで開始できるようにcidをポストするのではなく、学ぶのが好きです。私がh:linkを使用する場合、いくつかのパラメータを渡す必要があります(この例では、 "theProfile"オブジェクトをパラメータとして渡す必要があります)。 – cubbuk

0

私は

が同時要求が同じ対話コンテキストに関連付けられているため、コンテナが要求を拒否したことを示し、これを発見しました。

コンテナは、同時実行要求をブロックまたは拒否することにより、長期間の会話が一度に最大で1つの要求に関連付けられることを保証します。コンテナがリクエストを拒否した場合は、リクエストを新しい一時的な会話に関連付け、JSFライフサイクルのリストア・ビュー・フェーズでBusyConversationException型の例外をスローする必要があります。

は、私はまた私がクリックして使用したのと同じ問題に直面しhere

-1

を参照してください。

busyConevrsationはそのイベントで2つのアクションが発生しているので、commandLinkでそのクリックのイベント伝播を防ぐためにonclick="preventEventPropagation(event)";を使用しています。だから私は同じものを使用して、それは私のために働いています。

だから今BusyConversationExceptionを得ていないのです:)

+0

preventEventPropogrationはここでは役に立ちませんが、これはクリックリスナーがトリガーされている場合にのみ機能します。しかし、この場合、AJAXリクエストはすでにトリガされており、処理中であるか、実際のクリックの処理前にajax変更イベントによってトリガされます。このような問題を回避するには、保留中のAjaxリクエストを待ち受けて、リクエストが処理を終了するまでサブミットを延期する必要があります。私は自分の答えでブログの投稿をリンクしています。それは問題と解決策をより詳しく説明しています。 – dngfng

関連する問題