質問: JAX-RSを使ったWebアプリケーションを作っています。 下記の条件を全て満たすクラスからセッションにアクセスできるようにしたいのですが、方法が分かりません。 1. Beanではない任意の自作クラスである 2. 引数によってセッションにアクセスするオブジェクト(例えばHttpServletRequest)を入手できない ASP.NETの場合、`HttpContext.Current`というstaticプロパティを経由して、いつでもセッション(やその他のHTTP関連オブジェクト)にアクセスできます。 Java(JAX-RS)で同じような手段はありますか? やろうとしていることは色々あるのですが、例えば「ログインユーザのIDをデータアクセス層の入り口(各プログラマに対して隠蔽された共通基盤内部)でロギングする」といったものです。 ログインユーザの情報はセッションで保持しているのですが、この「共通基盤」と呼んでいるものは、**JAX-RSのWebサービスとはクラス間の関連としては全くつながっていません**。 つまり、同じアプリケーション上に存在するクラスではありますが、クラス間依存の連なりとか、そういう意味での繋がりは全くありません。 ですので、`HttpContext.Current`のように、グローバル変数のようなAPIがあれば助かります。 `@SessionScoped`でDIを使う方法も考えられますが、これだと隠蔽された共通基盤の中に組み込めないように思います。 あるいは、WebサービスのRequestFilterで(もっと適したものがある?)セッションから情報を取り出し、どこか共通クラスのstaticなフィールドにコピーするという考えも一瞬浮かびましたが、全くスレッドセーフではないのでNGでした。 ThreadLocalを使えば良いのかもしれませんが、ちょっと知識・経験不足で安全に実装できるかどうか、不安です。 他に手段が無ければ色々と調査・検証した上で導入する必要がありますが・・・ 何か良い方法は無いでしょうか? 環境は以下の通りですが、例えば「Spring Frameworkなら可」であれば、導入することも考えます。 アプリケーションサーバ:WildFly 使用フレームワーク:JavaEE7、Jersey(JAX-RS)
回答: @Context アノテーションを使って HttpServletRequest オブジェクトをインジェクトすることが可能です。 次のようにしてリソースメソッドのパラメータに `HttpServletRequest` オブジェクトを渡すことができます。 ``` @Path("/contacts") public class ContactService { @GET @Path("{id}") @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) public Contact find(@Context HttpServletRequest request, @PathParam("id") Long id) { return repository.find(id); } } ``` あとはこのメソッド内で HttpServletRequest#getSession() メソッドをコールして `HttpSession` オブジェクトを取得すれば良いでしょう。