Web サービスのカスタム処理の定義
まれに、着信メッセージの処理と応答メッセージの作成にカスタム処理を使用する InterSystems IRIS® データ・プラットフォーム Web サービスを定義すると便利な場合があります。これらのシナリオでは、ProcessBodyNode() メソッドか ProcessBody() メソッドのいずれかを Web サービスに実装します。ここでは、その詳細を説明します。
概要
カスタム処理では、手動で着信メッセージを解析して応答を作成します。要件は以下のとおりです。
-
Web サービスで、必要なシグニチャを持つ Web メソッドを定義します。これは、Web サービスの WSDL を設定するために行います。それらの Web メソッド (またはその一部) は、スタブとすることができます。メソッドは、ProcessBodyNode() または ProcessBody() が 0 を返す場合のみ実行されます。
-
また、Web サービスに、以下のメソッドのいずれかを実装します。
-
ProcessBodyNode() — このメソッドは、SOAP 本文を %XML.NodeOpens in a new tab のインスタンスとして受け取ります。InterSystems IRIS XML ツールを使用してこのインスタンスを扱い、応答メッセージを作成します。SOAP エンベロープは、%XML.NodeOpens in a new tab のこのインスタンスの Document プロパティにあります。
-
ProcessBody() — このメソッドは、SOAP 本文をストリームとして受け取ります。SOAP 本文は XML ドキュメントではなく XML フラグメントであるため、InterSystems IRIS XML ツールをその読み取りに使用することはできません。代わりに、ObjectScript 関数を使用してそのストリームを解析し、必要な部分を抽出します。
これらのメソッドを両方とも定義する場合、ProcessBodyNode() メソッドは無視されます。
-
いずれの場合も、作成する応答メッセージは Web サービスの WSDL と整合性がある必要があります。
ProcessBodyNode() の実装
ProcessBodyNode() メソッドには、以下のシグニチャがあります。
method ProcessBodyNode(action As %String, body As %XML.Node,
ByRef responseBody As %CharacterStream) as %Boolean
以下はその説明です。
-
action は、着信メッセージに指定されている SOAP アクションです。
-
body は、SOAP <Body> を含む %XML.NodeOpens in a new tab のインスタンスです。
-
responseBody は、%Library.CharacterStreamOpens in a new tab のインスタンスとしてシリアル化された応答本文です。このストリームは参照によって渡され、最初は空です。
このメソッドを Web サービスに実装する場合、このメソッドで以下を実行する必要があります。
-
action および分岐を適切に検証します。以下はその例です。
if action["action1" { //details }
-
SOAP <Envelope> にアクセスする必要がある場合は (例えば、そのネームスペース宣言にアクセスするなど)、body の Document プロパティを使用します。これは、SOAP エンベロープを DOM (ドキュメント・オブジェクト・モデル) として表現する %XML.DocumentOpens in a new tab のインスタンスと等しくなります。
それ以外の場合は、body を直接使用します。
-
ここで、以下のオプションがあります。
-
%XML.WriterOpens in a new tab を使用して本文を文字列として記述し、操作できるようにします。以下はその例です。
set writer=##class(%XML.Writer).%New() do writer.OutputToString() do writer.DocumentNode(body) set request=writer.GetXMLString(.sc) // check returned status and continue
-
必要に応じて、%XML.DocumentOpens in a new tab または %XML.NodeOpens in a new tab のメソッドを使用し、ドキュメントをナビゲートします。同様に、%XML.DocumentOpens in a new tab または %XML.NodeOpens in a new tab のプロパティを使用し、ドキュメントの現在の部分に関する情報にアクセスします。
-
XPath 式を使用して、データを抽出します。
-
XSLT 変換を実行します。
詳細は、"XML ツールの使用法" を参照してください。これらのクラス内のメソッドによって返されるステータスをチェックし、エラーが発生した場合のトラブルシューティングを簡素化するようにします。
-
-
要求の処理中にエラーが発生したら、ReturnFault() メソッドを使用する通常の方法でフォルトを返します。
-
応答ストリームの Write() メソッドを使用して、<Body> の子要素となる XML フラグメントを記述します。
-
応答ストリームが作成される場合は、1 を返します。それ以外の場合は 0 を返しますが、これによって、指定されたアクションに関連付けられた Web メソッドが実行されます。
以下はその例です。
if action["action1" { //no custom processing for this branch quit 0 } elseif action["action2" { //details //quit 1 }
ProcessBody() の実装
ProcessBody() メソッドには、以下のシグニチャがあります。
method ProcessBody(action As %String, requestBody As %CharacterStream,
ByRef responseBody As %CharacterStream) as %Boolean
以下はその説明です。
-
action は、着信メッセージに指定されている SOAP アクションです。
-
requestBody は、SOAP <Body> 要素を含む %Library.CharacterStreamOpens in a new tab のインスタンスです。ストリームには、完全な XML ドキュメントではなく、XML フラグメントが含まれます。
-
responseBody は、%Library.CharacterStreamOpens in a new tab のインスタンスとしてシリアル化された応答本文です。このストリームは参照によって渡され、最初は空です。
このメソッドを Web サービスに実装する場合、このメソッドで以下を実行する必要があります。
-
action および分岐を適切に検証します。以下はその例です。
if action["action1" { //details }
-
requestBody の Read() メソッドを使用して、SOAP <Body> を取得します。以下はその例です。
set request=requestBody.Read()
-
$EXTRACT などのツールを使用して、このストリームを解析します。以下はその例です。
set in1="<echoString xmlns=""http://soapinterop.org/xsd""><inputString>" set in2="</inputString></echoString>" set contents=$extract(request,$length(in1)+1,*-$length(in2))
-
要求の処理中にエラーが発生したら、ReturnFault() メソッドを使用する通常の方法でフォルトを返します。
-
応答ストリームの Write() メソッドを使用して、<Body> の子要素となる XML フラグメントを記述します。以下はその例です。
set in1="<echoString xmlns=""http://soapinterop.org/xsd""><inputString>" set in2="</inputString></echoString>" set request=requestBody.Read() if ($extract(request,1,$length(in1))'=in1) || ($extract(request,*-$length(in2)+1,*)'=in2) { do responseBody.Write("Bad Request: "_request) quit 1 } set out1="<echoStringResponse xmlns=""http://soapinterop.org/xsd""><echoStringResult>" set out2="</echoStringResult></echoStringResponse>" do responseBody.Write(out1) do responseBody.Write($extract(request,$length(in1)+1,*-$length(in2))) do responseBody.Write(out2)
-
応答ストリームが作成される場合は、1 を返します。それ以外の場合は 0 を返しますが、これによって、指定されたアクションに関連付けられた Web メソッドが実行されます。