ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Server JAX-RPC を使用した Web サービスの高度な機能のプログラミング
11g リリース 1 (10.3.1)
B55544-01
 

目次
目次

戻る
戻る
 
次へ
次へ
 

6 非同期機能の併用

以下の節では、非同期機能を併用する方法について説明します。

非同期機能の併用

ここまでの各節では、WebLogic Web サービスの非同期機能 (Web サービスの信頼性のあるメッセージング、会話、非同期の要求と応答、およびバッファリング) を単独で使用する方法を説明してきました。しかし通常、Web サービスではこれらの機能を併用しています。例については、「信頼性のある会話形式の Web サービスを実装する JWS ファイルの例」および「信頼性のある会話形式の Web サービスを非同期で呼び出すクライアント Web サービスの例」を参照してください。

併用すると、個々の機能についての節で説明した制限事項の一部が適用されなくなったり、場合によっては追加の制限事項が適用されたりします。次の表に、さまざまな機能を組み合わせる場合の考慮事項をまとめます。

表 6-1 非同期機能を一緒に使用する場合の考慮事項

機能の組み合わせ 考慮事項

非同期の要求/応答機能と Web サービスの信頼性のあるメッセージング/バッファ機能

  • 信頼性のある Web サービスからの非同期応答も信頼性がある。つまり、応答を処理するためには、送り先 WebLogic Server インスタンスをコンフィグレーションするのと同じように、ソース WebLogic Server インスタンス上でも JMS サーバ、モジュール、およびキューをコンフィグレーションする必要がある。

    ソース WebLogic Server インスタンス上で JMS キューを作成する際には、weblogic.wsee.DefaultQueue の JNDI 名を指定することが要求される。キューの名前は任意に付けることができる。また、この JMS キューが「ローカル」であることも指定する必要がある。通常は、ローカル JNDI 名の設定により指定できる。

  • 信頼性のあるオペレーションまたはバッファ付きのオペレーションを一方向にすることはできない。つまり、実装メソッドに @Oneway アノテーションを付加することはできない。

非同期の要求/応答機能と Web サービスの信頼性のあるメッセージング機能

非同期コンテキストのいずれか 1 つ (AsyncPreCallContext または AsyncPostCallContext) でプロパティを設定する場合、そのプロパティは java.io.Serializable を実装する必要がある。

非同期の要求/応答機能とバッファ機能

バッファ付き Web サービス オペレーションを呼び出すクライアント Web サービスで @ServiceClient JWS アノテーションを使用する必要がある。

会話機能と Web サービスの信頼性のあるメッセージング機能

  • JWS の会話は、信頼性のあるシーケンスとは異なり、いかなる方法によってもリンクされない。信頼性のあるシーケンスの管理は、会話のライフサイクルとは別に検討する必要がある。たとえば、信頼性のあるメッセージングを使用して、クライアント サービスと信頼性のある会話形式サービスとの間でメッセージを送信する場合、会話を終了しても信頼性のあるシーケンスは終了されない。信頼性のあるシーケンスは (WsrmUtils.setFinalMessage() などの許容可能なメソッドを使用して) 明示的に終了させる必要がある。または、シーケンスの有効期間が経過して期限切れになるまでアクティブにしておくことができる。信頼性のあるメッセージ シーケンスのライフサイクルの詳細については、「信頼性のあるメッセージ シーケンスのライフサイクルの管理」を参照。

  • プロパティ WLStub.CONVERSATIONAL_METHOD_BLOCK_TIMEOUT は、クライアント Web サービスのスタブに対して設定された場合、クライアントがブロックしないため無視される。

  • 信頼性のある会話形式の Web サービスの少なくとも 1 つのメソッドは、@Oneway アノテーションでマークしてはいけない。

会話機能と非同期の要求/応答機能

クライアントの会話形式の Web サービスとその他の Web サービスとの間における非同期の応答もまた、会話に参加する。たとえば、WebServiceA が会話形式であり、これが非同期の要求と応答を使用した WebServiceB の呼び出しを行う場合、WebServiceA が会話形式なので、WebServiceB からの非同期応答もまた、同じ会話に参加することになる。


信頼性のある会話形式の Web サービスを実装する JWS ファイルの例

次のサンプルの JWS ファイルでは、信頼性があり、かつ会話形式でもある Web サービスを実装しています。

package examples.webservices.async_mega;

import java.io.Serializable;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.Conversation;
import weblogic.jws.Policy;

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService(name="AsyncMegaPortType",
            serviceName="AsyncMegaService",
            targetNamespace="http://examples.org/")

@Policy(uri="AsyncReliableConversationPolicy.xml",
        attachToWsdl=true)

@WLHttpTransport(contextPath="asyncMega",
                 serviceUri="AsyncMegaService",
                 portName="AsyncMegaServicePort")

/**
 * 信頼性があり、かつ会話形式でもある Web サービス
 */

public class AsyncMegaServiceImpl implements Serializable {

  @WebMethod
  @Conversation (Conversation.Phase.START)
  public String start() {
    return "Starting conversation";
  }

  @WebMethod
  @Conversation (Conversation.Phase.CONTINUE)
  public String middle(String message) {
    return "Middle of conversation; the message is: " + message;
  }

  @WebMethod
  @Conversation (Conversation.Phase.FINISH)
  public String finish(String message ) {
    return "End of conversation; the message is: " + message;
  }

}

信頼性のある会話形式の Web サービスを非同期で呼び出すクライアント Web サービスの例

次の JWS ファイルでは、「信頼性のある会話形式の Web サービスを実装する JWS ファイルの例」に記載の Web サービスにおけるさまざまな会話形式のメソッドを確実に呼び出すクライアント Web サービスの実装方法を示します。クライアント JWS ファイルでは、非同期の要求と応答機能も使用しています。

package examples.webservices.async_mega;

import weblogic.jws.WLHttpTransport;
import weblogic.jws.ServiceClient;
import weblogic.jws.AsyncResponse;
import weblogic.jws.AsyncFailure;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.rpc.Stub;

import weblogic.wsee.async.AsyncPreCallContext;
import weblogic.wsee.async.AsyncCallContextFactory;
import weblogic.wsee.async.AsyncPostCallContext;
import weblogic.wsee.reliability.WsrmUtils;

import examples.webservices.async_mega.AsyncMegaPortType;
import examples.webservices.async_mega.AsyncMegaService;
import examples.webservices.async_mega.AsyncMegaService_Impl;

import java.rmi.RemoteException;

@WebService(name="AsyncMegaClientPortType",
            serviceName="AsyncMegaClientService",
            targetNamespace="http://examples.org/")

@WLHttpTransport(contextPath="asyncMegaClient",
                 serviceUri="AsyncMegaClient",
                 portName="AsyncMegaClientServicePort")

/**
 * AsyncMegaService との間で信頼性を伴い非同期に会話するクライアント 
 * Web サービス
 */

public class AsyncMegaClientImpl {

  @ServiceClient(
     wsdlLocation="http://localhost:7001/asyncMega/AsyncMegaService?WSDL",
     serviceName="AsyncMegaService",
     portName="AsyncMegaServicePort")

  private AsyncMegaPortType port;

  @WebMethod
  public void runAsyncReliableConversation(String message) {

    AsyncPreCallContext apc = AsyncCallContextFactory.getAsyncPreCallContext();
    apc.setProperty("message", message);

    try {
      port.startAsync(apc);
      System.out.println("start method executed.");

      port.middleAsync(apc, message );
      System.out.println("middle method executed.");

      // このサービスは会話ではないため、このメソッドを返す場合
      // [ポート] フィールドにあるすべての状態は消失します。信頼性のあるメッセージングの場合、
      // この状態には、メッセージの送信に使用されている
      // 信頼性のあるシーケンスの ID が含まれます。setFinalMessage メソッドは、このメッセージが
      // このシーケンスで送信される最終メッセージであることを指定する。これにより、
      // 信頼性のあるメッセージング サブシステムは、
      // 信頼性のあるシーケンスをタイムアウトさせる前にクリーンアップすることができます。      WsrmUtils.setFinalMessage((Stub)port);
      port.finishAsync(apc, message );
      System.out.println("finish method executed.");

    }
    catch (RemoteException e) {
      e.printStackTrace();
    }

  }

  @AsyncResponse(target="port", operation="start")
  public void onStartAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncResponse(target="port", operation="middle")
  public void onMiddleAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncResponse(target="port", operation="finish")
  public void onFinishAsyncResponse(AsyncPostCallContext apc, String message) {
    System.out.println("-------------------");
    System.out.println("Got message " + message );
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="start")
  public void onStartAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="middle")
  public void onMiddleAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }

  @AsyncFailure(target="port", operation="finish")
  public void onFinishAsyncFailure(AsyncPostCallContext apc, Throwable e) {
    System.out.println("-------------------");
    e.printStackTrace();
    System.out.println("-------------------");
  }
}