2012-05-06 3 views
4

私はSpring 3を使用しています。コントローラが要求を取得すると、サービスBeanで@Asyncというアノテーションが付けられたメソッドsomeMethod()に制御が渡されて戻ります。私はsomeMethod()のHttpSessionオブジェクトにアクセスすると、私はこの例外を受け取る最初に受信したスレッドの外部でHttpSessionにアクセスする

java.lang.IllegalStateException: No thread-bound request found: Are you 
referring to request attributes outside of an actual web request, or 
processing a request outside of the originally receiving thread? If you are 
actually operating within a web request and still receive this message, your 
code is probably running outside of DispatcherServlet/DispatcherPortlet: In 
this case, use RequestContextListener or 
RequestContextFilter to expose the current request. 

どのように私はこの問題を解決することができますか?

答えて

3

HttpSessionオブジェクト自体は複数のスレッドで使用できますが(ではなく、はスレッドセーフなので同期が必要です)。しかし、春はいくつか特別な魔法をやっています。 session - スコープされた豆があるとき。つまり、現在のセッションとスレッドをバインドするのに、ThreadLocalを使用します。

私はあなたの正確なシナリオが何であるかを知らないが、どうやら春はあなたが別のスレッドにいる間、このThreadLocalからHttpSessionを取得しようと - 明らかに失敗しました。

解決方法は簡単です。@Asyncメソッドで必要なセッション属性を抽出し、直接渡します。これは、はるかに優れた設計です。これにより、テストがより困難になり、将来的にコードが再利用される可能性が低くなるため、HttpSessionオブジェクトが回避されることはありません。

+0

あなたのソリューションはシンプルで良いですが、コントローラレイヤだけでなくビジネスレイヤやデータレイヤでも必要な場合は、どこにユーザー固有のデータを保存できますか?あるいは、これらのデータをメソッド引数で渡す必要がありますか?後者は唯一の解決策ですか? –

+0

@OleksandrBondarenko:考えてみましょう。サービス層のセッションにアクセスすると、隠れた結合と非明示的な依存関係が導入されます。引数を介してこのデータをすべて渡すことは、おそらく最良の選択肢です。 –

+0

しかし、セッションの設定はどうですか?リクエストの外でHttpSessionにアクセスできるというあなたのアサーションをバックアップするためのドキュメントがありますか? – mjaggard

関連する問題