ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの高度な機能のプログラミング
11g リリース1(10.3.3)
B61633-01
  目次へ移動
目次

前
 
次
 

12 HTTPセッションを使用したステートフルJAX-WS Webサービスのプログラミング

この章では、Oracleデータベースと対話するJAX-WS Webサービスの開発方法について説明します。

ステートフルWebサービスの概要

通常、JAX-WS Webサービスはステートレスです。つまり、Webサービス・オブジェクトに設定したローカル変数とオブジェクト値は、1つの呼出しから次の呼出しまでの間保存されません。1つのクライアントからの順次的な各リクエストも独立したステートレス・メソッド呼出しとして扱われます。

Webサービスの使用例として、クライアントが呼出しの途中でサービスにデータを保存しておき、その後の呼出しで保存したデータを使用するというものがあります。たとえば、ショッピング・カート・オブジェクトを、addToCart Webメソッドを繰り返し呼び出して追加した後、getCart webメソッドで取得するとします。ステートレスWebサービスでは、addToCartメソッド呼出しの数に関係なく、ショッピング・カート・オブジェクトは常に空となります。しかし、HTTPセッションを使用して複数のWebサービス呼出しにわたって状態を保持すれば、カートの中身を徐々に増やした後、カートをクライアントに戻すことができます。

JAX-WS Webサービスでのステートフル・サポートは、クライアント側、サーバー側ともに最小限のコーディングで有効にできます。

サーバーにHTTPセッションへのアクセス

サーバーでは、すべてのWebサービス呼出しがHttpSessionオブジェクトに関連付けられています。このオブジェクトは、リソース・インジェクションを使用してWebサービス・オブジェクトにバインドされているWebサービス・コンテキストからアクセス可能です。HttpSessionオブジェクトにアクセスしたら、それに任意のステートフル・オブジェクトを「ハング」オフできます。クライアントが次にWebサービスを呼び出すと、Webサービスは同じHttpSessionオブジェクトを見つけて、その中に以前格納したオブジェクトを参照することができます。これでWebサービスはステートフルになりました。

サーバーでの必要な手順は以下のとおりです。

  1. Webサービスの冒頭に(Common Annotations for the Java Platform、JSR 250で定義されています)@Resourceを追加します。

  2. コンテキストが注入されているWebServiceContext型の変数を追加します。

  3. Webサービス・コンテキストを使用してHttpSessionオブジェクトを取得します。

  4. setAttributeメソッドを使用してHttpSessionにオブジェクトを保存し、getAttributeを使用して格納されたオブジェクトを取得します。オブジェクトが割り当てる文字列値によって識別されます。

以下の断片は、その使い方を示しています。

例12-1 サーバーでのHTTPセッションへのアクセス

@WebService
public class ShoppingCart {
   @Resource    // Step 1
   private WebServiceContext wsContext;    // Step 2
   public int addToCart(Item item) {
      // Find the HttpSession
      MessageContext mc = wsContext.getMessageContext();    // Step 3
      HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
      if (session == null)
         throw new WebServiceException("No HTTP Session found");
      // Get the cart object from the HttpSession (or create a new one)
      List<Item> cart = (List<Item>)session.getAttribute("myCart");  // Step 4
      if (cart == null)
         cart = new ArrayList<Item>();
      // Add the item to the cart (note that Item is a class defined 
      // in the WSDL)
      cart.add(item);
      // Save the updated cart in the HTTPSession (since we use the same 
      // "myCart" name, the old cart object will be replaced)
      session.setAttribute("myCart", cart);
      // return the number of items in the stateful cart
      return cart.size();
   }
}

クライアントでのHTTPセッションの有効化

クライアント側コードはとても簡単です。必要なのは、リクエスト・コンテキストにSESSION_MAINTAIN_PROPERTYを設定することのみです。これにより、Webサービスから受信したHTTP Cookieを戻すようクライアントに指示します。Cookieには、サーバーがWebサービス呼出しを正しいHttpSessionと対応させるためのセッションIDが含まれており、これによって任意の保存済ステートフル・オブジェクトへのアクセスが可能になります。

例12-2 クライアントのHTTPセッションの有効化

ShoppingCart proxy = new CartService().getCartPort();
((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
// Create a new Item object with a part number of '123456' and an item 
// count of 4.
Item item = new Item('123456', 4);
// After first call, we'll print '1' (the return value is the number of objects 
// in the Cart object)
System.out.println(proxy.addToCart(item));
// After the second call, we'll print '2', since we've added another 
// Item to the stateful, saved Cart object.
System.out.println(proxy.addToCart(item));

セッション・ステート・レプリケーションを使用してクラスタ内のステートフル・サービスの開発

高可用性環境では、1つのJAX-WS Webサービスがクラスタ内の複数のサーバー・インスタンスにレプリケートされる場合があります。このような環境でステートフルJAX-WS Webサービスをサポートするには、WebLogic Server HTTPセッション状態レプリケーション機能を使用します。詳細は、『Oracle WebLogic Serverクラスタの使い方』のHTTPセッション状態レプリケーションに関する項を参照してください。

セッション状態レプリケーションを使用してクラスタ環境を設定するには、様々な手法と構成要件があります(たとえば、サポート対象のサーバーやロード・バランサなど)。JAX-WSプログラミングの視点から見ると、新たに考慮すべき点は、HttpSession.setAttributeメソッド(例12-1を参照)を使用してHttpSessionに格納するオブジェクトが、シリアライズ可能である必要があることのみです。シリアライズ可能な場合は、クラスタ内でレプリケートされたすべてのWebサービス・インスタンスにおいて、ステートフル・オブジェクトをWebサービスで使用できるようになり、JAX-WSステートフルWebサービスのロード・バランシング機能とフェイルオーバー機能が両方とも実現します。

JAX-WS RI @ステートフル拡張に関する注意

JAX-WS 2.1 Reference Implementation (RI)には、@Statefulアノテーションを使用してステートフルJAX-WS Webサービスの異なるモデルをサポートするベンダー拡張があります。その実装は、状態を特定のインスタンスに固定するもので、スケーラビリティやフォルト・トレランスを目的としていません。WebLogic Server JAX-WS Webサービスでは、この機能はサポートされません。