2012-05-08 10 views
1

JavaとJSFを初めて使用しました。私は、IllegalStateExceptionの助けが必要です。私はこのセッションでは、アプリケーションメニュー用のBeanをスコープ持っている私の現在のプロジェクトでセッションスコープ付きBeanから.getSessionMap()を実行しようとすると、IllegalStateExceptionが発生する

::ここでは、シナリオの私のロジックのいくつかの点で

public final class MenuBean implements Serializable{ 
    private MenuModel model; 
    private FacesContext context = FacesContext.getCurrentInstance(); 

    public MenuModel getModel() { 
     return model; 
    } 

    public MenuBean() { 
     updateMenu(); 
    } 

    public void updateMenu(){ 
     Map session = (Map<String,Object>) context.getExternalContext().getSessionMap(); 
     EUser user = (EUser) session.get(UserBean.USER_SESSION_KEY); 

     ... 
    } 

    private MethodExpression createMethodExpression(String action) { 
     ... 
    } 
} 

、私はメニューを更新する必要があるので、私はこれを行う:

ExternalContext extContext = context.getExternalContext(); 
Map sMap = (Map<String,Object>) extContext.getSessionMap(); 

MenuBean menu = (MenuBean) sMap.get("menuBean"); 
menu.updateMenu(); 

豆iは更新方法の1行目に乗るとIllegalStateExceptionが、罰金構築し、私はそれを手動で更新しようとすると、上記のようにupdateMenu()

何が問題なのか分かりません。メニューが初めてビルドされたときに、同じ呼び出しでセッションマップを取得できるためです。

また、NetBeansデバッガを使用すると、MenuBeanのインスタンスが正しくリカバリされていることがわかります。

あなたは私を助けることができますか?

答えて

2

FacesContextは、HTTP要求スレッドに格納されます。これを宣言して、HTTPリクエストよりも長く続くインスタンスのインスタンス変数として割り当てることは絶対に避けてください。 FacesContextインスタンスは解放され、HTTP要求が完了すると無効になります。後続のHTTPリクエストでは、インスタンスはもう有効ではありません。違法な状態の手段があります。それはあなたが見ているIllegalStateExceptionを説明しています。あなたは常に変数として割り当てることができ

Map<String, Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap(); 
// ... 

private FacesContext context = FacesContext.getCurrentInstance(); 

そして、メソッドブロックで、それが唯一のThreadLocalを取得するようにコードを修正する:あなたがに必要

次の行を削除しますしかし、それはスレッドローカルのみに保たれるべきです:

FacesContext context = FacesContext.getCurrentInstance(); 
Map<String, Object> sessionMap = context.getExternalContext().getSessionMap(); 
// ... 

無関係の具体的な問題には、@ManagedPropertyを使用すると、この特定のケースではより簡単でした。

public final class MenuBean implements Serializable { 

    @ManagedProperty("#{user}") 
    private EUser user; 

    // ... 
} 

JSFがあなたのために注入します。

+0

Hi BalusC。本当にありがとう。それがそれを解決しました。私はチュートリアルで(悪い)デザインを見ましたが、その後私のbeanのスコープを変更して、これが起こる可能性があることに気付かなかった。 –

+0

@ManagedPropertyがどのように動作するのかよくわかりませんでした。コンテナは "#{user}"をどのように解決しますか?これを定義する必要はありますか? –

+0

これは単にEL式を評価し、 'MenuBean'の構築の直後に検索されたオブジェクトでgetterメソッドを呼び出します。ここでは 'UserBean.USER_SESSION_KEY'の値が' user'であると仮定してELスコープで '#{user} 'として有効に利用できます。 – BalusC