![]() ![]() ![]() ![]() |
以下の節では、会話形式の Web サービスの作成方法について説明します。
Web サービスと、その Web サービスが呼び出すクライアント アプリケーションは、1 つのタスクを完了するために複数回通信する場合があります。また、複数のクライアント アプリケーションが同時に同じ Web サービスと通信する場合もあります。会話を使用すると、直接的な方法で、呼び出し間のデータを追跡して、Web サービスが常に正しいクライアントに応答するようにできます。
会話を使用すると、複数の通信にわたってデータを維持することに伴う以下の 2 つの問題が解決されます。
WebLogic Server はこのユニークな ID とステートを、クライアント アプリケーションが新しく会話を開始するたびに会話コンテキストを作成することによって管理します。Web サービスがその後、このコンテキストを使用して、サービスとの間の呼び出しを相関させ、ステート関連データを永続化します。
クライアント アプリケーションと Web サービスの間の会話には、明確なフェーズが 3 つあります。
会話は通常、2 つの WebLogic Web サービス間で発生します。そのうち 1 つは会話形式のものとしてマークされ、開始、続行、および終了のオペレーションを定義します。もう 1 つの Web サービスは @ServiceClient
アノテーションを使用して、それが会話形式の Web サービスのクライアントであることを指定します。また、制限事項はありますが、会話形式の Web サービスはスタンドアロン Java クライアントからも呼び出せます。
他の WebLogic Web サービスの機能と同様に、Web サービスを会話形式のものとして指定するには、JWS アノテーションを使用します。
注意 : | 会話形式の Web サービスを呼び出すクライアント Web サービスは、必ずしも会話形式にする必要はありません。ただし、クライアントが会話形式でない場合は、このクライアントの複数のインスタンスが同じ会話形式の Web サービス スタブにアクセスする危険性があり、保存されている会話状態が破損するおそれがあります。この危険性があると判断した場合は、クライアント Web サービスも会話形式になるように指定してください。その場合は、スタンドアロンの Java クライアントは使用できません。これは、WebLogic API を使用して会話形式であることを指定する方法がないためです。 |
注意 : | 会話形式の Web サービス自体は、必ず 1 回、メッセージの配信が行われることや、メッセージが順序どおりに配信されることを保証するものではありません。そのようなメッセージ配信保証が必要であれば、Web サービスが信頼性のあるものであることも指定する必要があります。「Web サービスの信頼性のあるメッセージングの使用」および「非同期機能の併用」を参照してください。 |
以下の手順では、会話形式の Web サービス、ならびにクライアント Web サービスおよびスタンドアロン Java クライアント アプリケーション (いずれも会話を開始および実施するもの) を作成する方法について説明します。この手順では、2 つの Web サービスを実装する JWS ファイルをゼロから作成する方法を示しています。既存の JWS ファイルを更新する場合は、この手順をガイドとして利用することもできます。
Ant ベースの開発環境を設定済みであり、かつ jwsc
Ant タスクを実行して、生成された会話形式の Web サービスをデプロイするためのターゲットを追加できる、作業用の build.xml
ファイルがあることが前提となっています。さらに、会話を開始するクライアント Web サービスをホストする、WebLogic Server インスタンスを同様に設定してあることも前提となっています。詳細については、『JAX-RPC を使用した WebLogic Web サービスの開始』の以下の節を参照してください。
prompt> ant build-mainService |
||
prompt> ant build-clientService |
||
次のサンプルでは、会話形式の Web サービスを実装する簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conversation;
import java.io.Serializable;
import weblogic.jws.WLHttpTransport;import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
import javax.jws.WebService;
import javax.jws.WebMethod;
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
@WebService(name="ConversationalPortType",
serviceName="ConversationalService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="conv",
serviceUri="ConversationalService",
portName="ConversationalServicePort")
/**
* 会話形式の Web サービス
*/
public class ConversationalServiceImpl implements Serializable {
@Context
private JwsContext ctx;
public String status = "undefined";
@WebMethod@Conversation (Conversation.Phase.START)
public String start() {
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
status = "start";
return "Starting conversation, with ID " + convID + " and status equal to " + status;
}
@WebMethod@Conversation (Conversation.Phase.CONTINUE)
public String middle(String message) {
status = "middle";
return "Middle of conversation; the message is: " + message + " and status is " + status;
}
@WebMethod@Conversation (Conversation.Phase.FINISH)
public String finish(String message ) {
status = "finish";
return "End of conversation; the message is: " + message + " and status is " + status;
}
}
会話形式の Web サービスを実装している JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのサンプル コードは、上述のサンプルでは太字で示されています。
java.io.Serializable
を実装していなければならないので、まず JWS ファイルにクラスをインポートする必要がある。import java.io.Serializable;
import weblogic.jws.Conversation;
import weblogic.jws.Conversational;
@Context
アノテーションおよびコンテキスト API をインポートする。import weblogic.jws.Context;
import weblogic.wsee.jws.JwsContext;
import weblogic.wsee.jws.ServiceHandle;
実行時の Web サービス コンテキストの詳細については、『JAX-RPC を使用した WebLogic Web サービスの開始』の「Web サービスの実行時情報へのアクセス」を参照してください。
@Conversational
アノテーションを使用して、Web サービスを会話形式のものであると指定する。このアノテーションは任意指定ですが (メソッド レベルの @Conversation
アノテーションを指定していると仮定した場合)、常にこれを JWS ファイル内で使用して、Web サービスが会話形式であると明確に指定することをお勧めします。
指定する任意の属性は、WebLogic Server が会話を終了するまでの、Web サービスがアイドル状態でいられる最大時間 maxIdleTime
、会話の最大存続期間 maxAge
、既存の会話の続行フェーズと終了フェーズを、会話を開始したユーザとして実行するかどうかを示す runAsStartUser
、会話を開始したユーザ以外のユーザが、会話の続行フェーズと終了フェーズの実行を許可されるかどうかを示す singlePrincipal
のうちのいずれかです。
@Conversational(maxIdleTime="10 minutes",
maxAge="1 day",
runAsStartUser=false,
singlePrincipal=false )
JWS ファイルに @Conversational
アノテーションが含まれている場合、Web サービスのすべてのオペレーションが会話形式です。オペレーションのデフォルトのフェーズは、明示的に @Conversation
アノテーションが指定されていなければ、続行フェーズです。ただし、会話形式の Web サービスには、1 つ以上の開始オペレーションと、1 つの終了オペレーションが含まれていることが必要なので、メソッド レベルの @Conversation
アノテーションを使用して、これらのオペレーションをどのメソッドで実装するかを指定する必要があります。
属性の詳細とデフォルト値については、『WebLogic Web サービス リファレンス』の「weblogic.jws.Conversational」を参照してください。
java.io.Serializable
が実装されている必要がある。public class ConversationalServiceImpl implements Serializable {
weblogic.wsee.jws.JwsContext
のプライベート クラス変数に、フィールド レベルの @Context
JWS アノテーションを付ける。@Context
private JwsContext ctx;
@Conversation
アノテーションを使用して、会話の開始、続行、および終了フェーズを実装するメソッドを指定する。会話には、1 つ以上の開始オペレーションと、1 つの終了オペレーションが必要です。続行オペレーションは任意指定です。フェーズを指定するアノテーションには、Conversation.Phase.START
、Conversation.Phase.CONTINUE
、または Conversation.Phase.FINISH
の各パラメータを使用します。次の例では、開始オペレーションを指定しています。@WebMethod
@Conversation (Conversation.Phase.START)
public String start() {...
@Conversation
アノテーションでマークする JWS ファイルのメソッドが 1 つのみの場合、Web サービス全体が会話形式となり、各オペレーションは、会話の一部と見なされます。これは、JWS ファイルで任意指定のクラス レベル @Conversational
アノテーションを使用していなかった場合でも当てはまります。@Conversational
で明示的にアノテーション付きにされていないメソッドはすべて、デフォルトで続行オペレーションとなります。つまり、たとえばクライアント アプリケーションが、それ以前に開始オペレーションを呼び出していない状態でこれらの続行メソッドの 1 つを呼び出すと、Web サービスが実行時エラーを返すということです。
なお、スタンドアロン Java クライアントから会話形式の Web サービスを呼び出す場合、開始オペレーションは要求と応答であることが必要です。言い換えると、このオペレーションに、@Oneway
JWS アノテーションを付けることはできません。オペレーションは、void
を返すことがあります。Web サービスを、WebLogic Server で実行されているクライアント アプリケーションからのみ呼び出す場合、この要件は適用されません。
詳細については、『WebLogic Web サービス リファレンス』の「weblogic.jws.Conversation」を参照してください。
JwsContext
インスタンスを使用する。
たとえば、開始オペレーションの次のコードでは、WebLogic Server が新しい会話に割り当てる ID を取得します。
ServiceHandle handle = ctx.getService();
String convID = handle.getConversationID();
コンテキスト関連 API の使用に関する詳細については、『JAX-RPC を使用した WebLogic Web サービスの開始』の「JwsContext を使用した実行時情報へのアクセス」を参照してください。
次の例では、「会話形式の JWS ファイルに関するプログラミングのガイドライン」で説明した会話形式の Web サービスを呼び出す Web サービス用の簡単な JWS ファイルを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conversation;
import weblogic.jws.WLHttpTransport;import weblogic.jws.ServiceClient;
import weblogic.wsee.conversation.ConversationUtils;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.rpc.Stub;
import examples.webservices.conversation.ConversationalPortType;
import java.rmi.RemoteException;
@WebService(name="ConversationalClientPortType",
serviceName="ConversationalClientService",
targetNamespace="http://examples.org/")
@WLHttpTransport(contextPath="convClient",
serviceUri="ConversationalClient",
portName="ConversationalClientPort")
/**
* ConversationalService と会話を行うクライアント
*/
public class ConversationalClientImpl {
@ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@WebMethod
public void runConversation(String message) {
try {
// 開始オペレーションを呼び出すString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// 続行オペレーションを呼び出すresult = port.middle(message );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// 終了オペレーションを呼び出すresult = port.finish(message );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);ConversationUtils.renewStub((Stub)port);
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
会話形式の Web サービスを呼び出す JWS ファイルをプログラミングする際には、以下のガイドラインに従います。ガイドラインのサンプル コードは、上述のサンプル内では太字で示されています。
@ServiceClient
JWS アノテーションをインポートする。import weblogic.jws.ServiceClient;
import weblogic.wsee.conversation.ConversationUtils;
jwsc
Ant タスクによって作成されます。スタブ パッケージは、<jws>
の子要素 <clientgen>
の packageName
属性によって指定され、スタブの名前は呼び出された Web サービスの WSDL によって決まります。import examples.webservices.conversation.ConversationalPortType;
@ServiceClient
JWS アノテーションを使用して、呼び出したい会話形式の Web サービスの WSDL、名前、およびポートを指定する。このアノテーションは、プライベート変数のフィールド レベルで指定します。この変数のデータ型は、呼び出している Web サービスの JAX-RPC ポート タイプとなります。 @ServiceClient(
wsdlLocation="http://localhost:7001/conv/ConversationalService?WSDL",
serviceName="ConversationalService",
portName="ConversationalServicePort")
private ConversationalPortType port;
@ServiceClient
アノテーションを付けたスタブを使用して、会話形式の Web サービスの開始オペレーションを呼び出し、会話を開始する。開始メソッドは、JWS ファイルの任意の場所 (コンストラクタ、メソッドなど) から呼び出せます。
String result = port.start();
result = port.middle(message );
result = port.finish(message );
weblogic.wsee.conversation.ConversationUtils
ユーティリティ クラスの renewStub()
メソッドを使用して、そのスタブを明示的に更新する必要がある。ConversationUtils.renewStub((Stub)port);
注意 : | 会話形式の Web サービスを呼び出すクライアント Web サービスは、必ずしも会話形式にする必要はありません。ただし、クライアントが会話形式でない場合は、このクライアントの複数のインスタンスが同じ会話形式の Web サービス スタブにアクセスする危険性があり、保存されている会話状態が破損するおそれがあります。この危険性があると判断した場合は、クライアント Web サービスも会話形式になるように指定してください。 |
WebLogic Server には、会話機能で使用するユーティリティ クラスが用意されています。このクラスを使用すると、会話 ID の取得や設定、コンフィグレーション オプションの設定といった一般的なタスクを実行できます。これらのタスクには、会話形式の Web サービス内で実行するものと、会話形式の Web サービスを呼び出すクライアント内で実行するものがあります。このクラスの使用例については、「会話形式の Web サービスを呼び出す JWS ファイルに関するプログラミングのガイドライン」を参照してください。
詳細については、Javadoc の「weblogic.wsee.conversation.ConversationUtils」を参照してください。
build.xml
ファイルを更新して、会話形式の Web サービスを呼び出す JWS ファイルを生成するには、次のサンプルのような taskdefs
および build-clientService
ターゲットを追加します。詳細については、サンプルの後の説明を参照してください。
<taskdef name="jwsc"
classname="weblogic.wsee.tools.anttasks.JwscTask" />
<target name="build-clientService">
<jwsc
enableAsyncService="true"
srcdir="src"
destdir="${clientService-ear-dir}" >
<jws file="examples/webservices/conversation/ConversationalClientImpl.java" ><clientgen
wsdl="http://${wls.hostname}:${wls.port}/conv/ConversationalService?WSDL"
packageName="examples.webservices.conversation"/>
</jws>
</jwsc>
</target>
jwsc
Ant タスクの完全なクラス名を定義するには、taskdef
Ant タスクを使用します。
クライアント Web サービスをコンパイルする jwsc
Ant タスクを更新して、<jws>
要素の <clientgen>
子要素を含めます。これにより、デプロイされた ConversationalService
Web サービスの JAX-RPC スタブが生成およびコンパイルされるようになります。jwsc
Ant タスクでは、これらのスタブが生成された WAR ファイルに自動的にパッケージ化されるため、即座にクライアント Web サービスからアクセスできるようになります。このようにするのは、生成されたクラスの 1 つを ConversationalClientImpl
JWS ファイルでインポートして使用するためです。
次の例では、「会話形式の JWS ファイルに関するプログラミングのガイドライン」で説明した会話形式の Web サービスを呼び出す、簡単なスタンドアロンの Java クライアントを示します。太字で示された Java コードに対応するコーディングのガイドラインについては、サンプルの後の説明を参照してください。
package examples.webservices.conv_standalone.client;
import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.Stub;
import weblogic.wsee.jaxrpc.WLStub;
/**
* ConversationalService を呼び出し、これと会話するスタンドアロン クライアント
*/
public class Main {
public static void main(String[] args)
throws ServiceException, RemoteException{
ConversationalService service = new ConversationalService_Impl(args[0] + "?WSDL");
ConversationalPortType port = service.getConversationalServicePort();
// スタブ上のプロパティを設定して、クライアントが高度な機能を使用する Web
// サービスを呼び出していることを指定する。このプロパティは、クライアントが
// WebLogic Server インスタンスで実行されている場合には自動的に設定される
Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
// 開始オペレーションを呼び出して会話を開始するString result = port.start();
System.out.println("start method executed.");
System.out.println("The message is: " + result);
// 続行オペレーションを呼び出すresult = port.middle("middle" );
System.out.println("middle method executed.");
System.out.println("The message is: " + result);
// 終了オペレーションを呼び出すresult = port.finish("finish" );
System.out.println("finish method executed.");
System.out.println("The message is: " + result);
}
}
会話形式の Web サービスを呼び出すスタンドアロン Java クライアントをプログラミングする際には、以下のガイドラインに従います。ガイドラインのサンプル コードは、上述のサンプルでは太字で示されています。
weblogic.wsee.jaxrpc.WLStub
クラスをインポートする。import weblogic.wsee.jaxrpc.WLStub;
_setProperty
メソッドを使用して、WLStub.Complex
プロパティを ConversationalService
の JAX-RPC スタブに対して設定する。Stub stub = (Stub)port;
stub._setProperty(WLStub.COMPLEX, "true");
このプロパティは、クライアントが高度な Web サービス (この場合は会話形式の Web サービス) を呼び出すことを Web サービスのランタイムに対して指定します。このプロパティは、別の WebLogic Web サービスから会話形式の Web サービスを呼び出している場合には、自動的に設定されます。
String result = port.start();
result = port.middle(message );
result = port.finish(message );
WebLogic Server では、プロダクションの再デプロイメントがサポートされています。つまり、会話形式の WebLogic Web サービスの更新後の新しいバージョンを、同じ Web サービスの古いバージョンと並行してデプロイできます。
WebLogic Server では、新しいクライアントのリクエストのみが新しいバージョンに転送されるように、クライアント接続が自動的に管理されます。再デプロイメント時にすでに Web サービスに接続していたクライアントは、作業が完了するまで古いバージョンのサービスを使用し続けます。作業が完了した時点で、自動的に古い Web サービスが廃止されます。クライアントが会話形式の Web サービスに接続されている場合は、既存の会話がクライアントによって明示的に終了されるか、またはタイムアウトになったときに、そのクライアントの作業が完了したと見なされます。
プロダクションの再デプロイメントと Web サービス クライアントの詳細については、『JAX-RPC を使用した WebLogic Web サービスの開始』の「Web サービスを再デプロイする際にクライアント側で考慮すべき事項」を参照してください。
![]() ![]() ![]() |