6

クラスのメソッドをFacesContext呼び出して を取得しようとしていますが、 が返されます。FacesContext.getCurrentInstance()run()Runnablenull

public class Task implements Runnable {

    @Override
    public void run() {
        FacesContext context = FacesContext.getCurrentInstance(); // null!
        // ...
    }

}

これはどのように発生し、どうすれば解決できますか?

4

1 に答える 1

13

は、 を呼び出した HTTP 要求を担当するスレッド( を作成する担当のスレッド)FacesContextに変数として格納されます。このスレッドは通常、JSF マネージド Bean メソッドのみを通過します。は、そのスレッドによって生成された他のスレッドでは使用できません。ThreadLocalFacesServletFacesContextFacesContext

実際には、他のスレッドでも必要ないはずです。さらに、スレッドが独立して開始および実行されると、基になる HTTP 要求はすぐに HTTP 応答の処理を続行し、その後消えます。とにかく、HTTP 応答で何かを行うことはできません。

問題を別の方法で解決する必要があります。自問してください:何のためにそれが必要ですか?情報を得るには?代わりに、その情報を構築中に に渡すだけです。Runnable

以下の例では、スレッド内のセッション スコープ オブジェクトにアクセスすることを前提としています。

public class Task implements Runnable {

    private Work work;

    public Task(Work work) {
        this.work = work;
    }

    @Override
    public void run() {
        // Just use work.
    }

}
Work work = (Work) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("work");
Task task = new Task(work);
// ...

ただし、スレッドの作業が終了したことなどを最終的にクライアントに通知する必要がある場合は、faces メッセージなどを追加するなどとは別の解決策を探す必要があります。答えは「プッシュ」を使用することです。これは、SSE または WebSocket を使用して実現できます。具体的な websockets の例は、この関連する質問で見つけることができます: Real time updates from database using JSF/Java EE。PrimeFaces を使用する場合は、 を参照してください <p:push>。たまたま OmniFaces を使用している場合は、 をご覧ください<o:socket>


具体的な問題とは関係ありませRunnableんが、Java EE Web アプリケーションで手動で を作成し、手動でスレッドを生成することは憂慮すべきことです。次の Q&A にアクセスして、すべての注意事項と実際の対処方法を確認してください。

于 2010-05-10T14:29:07.273 に答える