2012-03-16 13 views
3

背景:MyFacesを使用しているJSF 2.0アプリケーションがあります。このアプリケーションを使用すると、ユーザーはさまざまなJSFページを調べることによって、複雑な「ウィジェット」を作成します。セッションスコープにマネージドBeanを格納していて、ユーザーが各ページを通過するときにプロパティが設定されます。 「ウィジェット」の組み立てが完了したら、新しい「ウィジェット」を作成してそのプロセスを繰り返すことになります。私の質問は、JSFライフサイクルを中断することなく、マネージドBeanをセッションから完全に(安全に)削除する方法です。JSF 2.0でSessionスコープBeanを削除する方法(そしていつ?)

セッションを無効にすることができ、FacesContextを介してHttpSessionにアクセスし、そのようにBeanを削除できることを示唆する同様の質問に対するその他の回答を見ました。ユーザーにログアウトまたは再ログインをさせたくないので、セッション全体を無効にする必要はありません。 FacesContextを経由してHttpSessionにアクセスしてBeanを削除する必要があると仮定すると、JSFライフサイクルが安全にこれを実行して残りのサイクルをカスケードしないようにする最も適切な場面はいつですか?ユーザーが次の「ウィジェット」の作成プロセスを開始したときにJSFが新しいセッションBeanを作成するのに問題がないことを確認したい。

これを簡単にするためにJSFにメカニズムがない理由を知りたいと思っています。私が取るべき他のアプローチは、意図したJSFパターンに沿った方が良いでしょうか?ここでは、ビュースコープを使用することはできません。マネージドBeanは、完了する前にいくつかの異なるページとビューを通過するためです。

ありがとうございました!

答えて

2

条件付きで複数のウィザードステップをレンダリングする単一のページを作成します。

<h:panelGroup rendered="#{wizard.step == 1}"> 
    <ui:include src="/WEB-INF/wizard/step1.xhtml" /> 
</h:panelGroup> 
<h:panelGroup rendered="#{wizard.step == 2}"> 
    <ui:include src="/WEB-INF/wizard/step2.xhtml" /> 
</h:panelGroup> 
<h:panelGroup rendered="#{wizard.step == 3}"> 
    <ui:include src="/WEB-INF/wizard/step3.xhtml" /> 
</h:panelGroup> 

あなただけのあまり手間をかけずに、この単一ページに@ViewScopedマネージドBeanを使用することができますこの方法。具体的な質問とは無関係の


PrimeFacesはほぼ正確にそのようにし<p:wizard>成分を有しています。あなたは、妥当性チェックなどの厄介な定型コードから自分を救うために役立つかもしれません。

+0

ありがとうBalusC、私はこれが今の状況ではうまくいくと思います。より複雑なアプリでは、これはもっと問題になるかもしれません。セッションBeanを処理するのは本当に面倒ですか? – tcprogrammer

+0

これでViewScope Beanを使い終わりました。ありがとう! – tcprogrammer

0

まだ私自身は使っていませんが、CDIのConversationScopeを見ていきます。

+0

現在はサーブレットコンテナを使用していますが、完全なJ2EEコンテナは使用しませんが、今後の検討のために注意していきます。 – tcprogrammer

+0

CDIを[Weld reference implementation](http://docs.jboss.org/weld/reference/1.0.0/en-US/html/environments.html#d0e4910)からサーブレットコンテナに追加できます。 – fischermatte

1

ウィジェット作成データが単一のBeanにカプセル化されている場合は、ケースを簡略化できます。 は、私はあなたがポインタを取るし、それに応じて適応することができます

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

(最初のウィジェット作成ページでのみ)ビューでresetWidgetについては

@SessionScoped 
@ManagedBean 
public class WidgetMaker { 
    private Widget widget; 

    public void makeWidget(){ 
    //after creating/saving widget 
    widget = new Widget(); 
    } 

    public void resetWidget(){ 
    //this method can be called with pre render view handler 
    //call this method on the first page that starts widget creation 
    //in case person leaves the widget creation in between and starts over again 
    widget = new Widget(); 
    } 
} 

を意味します。

これが役に立ちます。

+0

エンドユーザが新しいブラウザタブでウィジェットのページを半段階のマルチステッププロセスで開くとどうなりますか?確かに、それらの2つのタブ/ウィンドウはお互いを乱すだろう。 – BalusC

+0

@BalusCは説明ごとにちょうど答えましたが、その落とし穴は明らかでした。 –

+0

私の場合、EntityManagerのようなスレッドセーフではないことをしばしば要求する範囲内にコントローラ/バッキングBeanがあります。セッションBeanがそれに注入されます。この設計では、preRenderViewはセッションBeanを排除するメソッドを実行する安全な場所になるでしょうか? – tcprogrammer

0

私はBalusCに同意します。あなたの場合、ビュースコープがより良い選択となるでしょう。セッションスコープでマルチページ形式のJSFプロジェクト(非常に古い)を調べました。後で私はよく知られている理由で状態を見るように切り替えました。

しかし、私はセッションは単にセッションマップでインスタンスを置き換えることにより、Beanをスコープリセットしました:

MyBean newInstance = new MyBean(); 
FacesContext.getCurrentInstance().getExternalContext() 
    .getSessionMap().put(beanName, newInstance); 

beanNameでBeanのEL名(文字列)として。

+0

私の記事で述べたように、私はセッションマップのBeanにアクセスする方法を知っていましたが、JSFライフサイクルのどこでこのアクションを実行して安全に行うのですか? – tcprogrammer

+0

私はこれが正しいフェーズかどうかを決して気にしないコマンドボタンアクションメソッドでそれを行いました。 –

関連する問題