CXFで作ったWebサービスからHttpServletRequestにアクセスしたい
SpringとApache CXFで簡単に Webサービスを作る の続き。
本来HTTPに依存しないはずのSOAPとはいえど、非Webサービス(普通のHTMLベースなWebアプリケーション)との連携を簡単にするためには HTTP Cookieでの状態保持に対応するのが現実的だ。
理想のことはともかく Webサービスから HttpServletRequestなど HTTPに依存するコンテキストにアクセスしたい場合、 javax.annotation.ResourceアノテーションでWebサービスフレームワークにその事を教えてやることによってコンテキスト情報へアクセスするための仲介オブジェクト javax.xml.ws.WebServiceContext をインジェクトしてもらえる。
のようにする。あとはクッキーでもセッションでもクライアント情報でも好きなようにどうぞ。
えーと、うちはWebサービスの実装クラスをシングルトンにしてるんだけど(Springで普通にやるとそうなる)、大丈夫なのこれ?という疑問が沸いたので Apache CXFのソースを調べてみたところ、WebServiceContextの実装で ThreadLocalなデータを持ってるようだったのでそこらへんはケアされてるのだろうと判断した。
リモートメソッドのコンカレントな呼び出しも試したところ、ちゃんと同時実行されているようだったので、synchronized { /* リクエストのはじまりからおわりまで */ } みたいなアホアホ実装でもないらしい。ちゃんとしてるね。あたりまえか。
本来HTTPに依存しないはずのSOAPとはいえど、非Webサービス(普通のHTMLベースなWebアプリケーション)との連携を簡単にするためには HTTP Cookieでの状態保持に対応するのが現実的だ。
理想のことはともかく Webサービスから HttpServletRequestなど HTTPに依存するコンテキストにアクセスしたい場合、 javax.annotation.ResourceアノテーションでWebサービスフレームワークにその事を教えてやることによってコンテキスト情報へアクセスするための仲介オブジェクト javax.xml.ws.WebServiceContext をインジェクトしてもらえる。
@Resource private WebServiceContext context;この contextオブジェクトから HttpServletRequestの参照へたどり着くには、
public void setContext(WebServiceContext context) {
this.context = context;
}
MessageContext ctx = context.getMessageContext();
HttpServletRequest request =
(HttpServletRequest) ctx.get(AbstractHTTPDestination.HTTP_REQUEST);
のようにする。あとはクッキーでもセッションでもクライアント情報でも好きなようにどうぞ。
えーと、うちはWebサービスの実装クラスをシングルトンにしてるんだけど(Springで普通にやるとそうなる)、大丈夫なのこれ?という疑問が沸いたので Apache CXFのソースを調べてみたところ、WebServiceContextの実装で ThreadLocalなデータを持ってるようだったのでそこらへんはケアされてるのだろうと判断した。
リモートメソッドのコンカレントな呼び出しも試したところ、ちゃんと同時実行されているようだったので、synchronized { /* リクエストのはじまりからおわりまで */ } みたいなアホアホ実装でもないらしい。ちゃんとしてるね。あたりまえか。

0 件のコメント:
コメントを投稿
<< ホーム