本文へジャンプ

ソフトウェア > Lotus > Lotus Developer Domain > 製品別技術情報 > Lotus Notes/Domino > 

LDD Today

Lotus Notes/Domino 7 Web サービス


Lotus Software
by Robert Perron
Documentation architect, IBM Corporation
レベル:上級者
原文の掲載:2004年9月27日

LDD Today の原文(US)



サンプル   Web サービス設計要素
基本的なコーディング   Web サービスの呼び出しとテスト
詳細プロパティ   セキュリティ
Web サービスのコンテキスト   複合データ型
データ型の対応   プライベート・プロシージャー
まとめ   リソース



Web サービスは Lotus Notes/Domino 7 では新しくなっています。この記事では、新しい Web サービス設計要素を取り上げ、Domino Designer を使用して Web サービスを作成する方法や、LotusScript と Java の両方のサンプル・コードを使用して Web サービスを実装する方法について解説します。

メモ:この記事は、Lotus Notes/Domino 7 Beta 2 での Web サービスの実装に基づいて書かれています。このため、記事の内容が、Notes/Domino 7 の Gold バージョンでの機能と正確に一致しない場合もあります。

Web サービスは、インターネット経由のメッセージ送信で呼び出すことができるリモート・オペレーションのアーカイブです。Web サービス・プロバイダーは検索と使用を目的として Web サービスを発行し、Web サービス・コンシューマーはこのサービスからオペレーションを呼び出します。Web サービス・プロバイダーは、サービス・インターフェースを定義する WSDL (Web Services Description Language) 文書を利用します。WSDL 文書は XML 形式です。インターフェースの裏側で何が行われるかはプロバイダーによって決められますが、ほとんどのプロバイダーでは、インターフェースは、サポートされているプログラミング言語でのプロシージャー呼び出しにマッピングされます。コンシューマーからの入力リクエストは、背景のコードによって処理され、その結果がコンシューマーに送り返されます。

Lotus Domino では、WSDL インターフェースは、エージェントに似た Web サービス設計要素にマッピングされます。Web サービス設計要素は、LotusScript または Java を使用してコーディングできます。Web サービスを使用する際は、HTTP が有効な Domino Server に Web サービスを配置する必要があります。(ただし、Notes Client のプリビューで、HTTP セッションを介して Web サービスをテストできます。)アクセスは、次のいずれかの Domino URL コマンドによって行われます。

  • OpenWebService は、HTTP POST で送信された SOAP エンコード・メッセージへのレスポンスとして Web サービスを起動します。HTTP GET (たとえば、ブラウザの検索) は、サービスの名前とそのオペレーションを返します。
  • WSDL は、HTTP GET へのレスポンスとして WSDL 文書を返します。

この記事では、Lotus Notes/Domino 7 の Web サービス設計要素について説明し、LotusScript と Java でコーディングしたこの設計要素の例を示します。この記事は、Notes アプリケーション開発の経験があり、LotusScript または Java の知識を持っている読者を想定しています。

サンプル
説明のために、簡単なサンプルを取り上げます。データベース名、ビュー名、および文書番号が指定されたときに、Subject アイテムの内容を返すオペレーションです。オペレーションの名前は getNthSubject です。

図 1. getNthSubject の図
getNthSubject の図

外部の世界に対してオペレーションを利用可能にするために、GetSubject という Web サービスでこのオペレーションを発行します。GetSubject には、任意の数のオペレーションを含められます。たとえば、getFirstSubject と getLastSubject があれば便利でしょう。しかし、ここではサンプル・オペレーションの getNthSubject だけを扱うことにします。このようなオペレーションを含む Web サービスを記述する WSDL 文書からの抜粋を以下に示します。その後の説明に沿って、この内容を見ていきましょう。

<wsdl:message name="getNthSubjectRequest"> (4)
 <wsdl:part name="dbname" type="xsd:string"/> (5)
 <wsdl:part name="viewname" type="xsd:string"/> (5)
 <wsdl:part name="n" type="xsd:int"/> (5)
</wsdl:message>
<wsdl:message name="getNthSubjectResponse"> (4)
<wsdl:part name="getNthSubjectReturn" type="xsd:string"/> (6)
</wsdl:message>
<wsdl:portType name="GetSubjectPortType"> (1)
 <wsdl:operation name="getNthSubject"
  parameterOrder="dbname viewname n"> (2)
 <wsdl:input message="impl:getnthSubjectRequest" name="GetNthSubjectRequest"/> (3)
 <wsdl:output message="impl:getNthSubjectResponse" name="GetNthSubjectResponse"/> (3)
 </wsdl:operation>
</wsdl:portType>

最初に、portType 要素 (1) を見てください。この要素は、サービスのオペレーションのセットを定義します。このサービスには portType が 1 つだけあり、これは getNthSubject という 1つのオペレーションを持ちます (2)。オペレーションには入力用と出力用の 2 つの「メッセージ」があります (3)。メッセージは、message 要素で定義されています (4)。入力メッセージは 3 つのパートに分かれています (5)。dbname と viewname という名前の 2 つのストリングと、n という名前の 1つの整数です。出力メッセージには、getNthSubjectReturn という名前のストリングのパートが 1 つあります (6)

つまり、サンプルのオペレーションは 3 つの入力パートと 1 つの出力パートを持つことになります。これは、3 つの読み込み専用パラメーターと 1 つの戻り値を持つプロシージャーにたいへんよく似ています。LotusScript では、このようなプロシージャーは次の関数によって定義できます。

Public Function getNthSubject(dbname As String, viewname As String, n As Long) As String

また、Java では、次のメソッドによって定義できます。

public String getNthSubject(String dbname, String viewname, int n)
 
上に戻る
 
Web サービス設計要素
Domino Designer では、さまざまな手法で Web サービス設計要素を作成できます。LotusScript または Java を使用してすべてをコーディングすることも可能です。コーディングした場合は、設計要素を保存すると、LotusScript または Java のコードを反映した WSDL 文書が生成されます。また、既存の WSDL 文書をインポートすることもできます。この場合は、インポートした WSDL 文書内のオペレーションを反映する LotusScript または Java が生成されます。Web サービス設計要素では、コードだけでなく WSDL 文書も保存されます。パブリック・インターフェースが変更されていない場合は、WSDL はそのままの状態で維持されます。パブリック・インターフェースに影響するコード変更を行うと、新規の WSDL が生成されます。

Domino Designer では、Web サービス設計要素は [共有コード] の [エージェント] の下にあります。Web サービスの設計ウィンドウは、エージェントの設計ウィンドウにたいへんよく似ています。[New Web Service] ボタンをクリックすると、新規の Web サービスが作成されます。既存の Web サービスを編集するときは、その Web サービスをダブルクリックします。

図 2. 新規の Web サービス
新規の Web サービス

[Web Services] プロパティボックスには、エージェントと同様に 3 つのタブがあります。[基本] タブを次の図に示します。

図 3. [Web Services] プロパティボックス
[Web Services] プロパティボックス

名前は必須です。別名とコメントは、入力してもしなくてもかまいません。コードの変更によって新規の WSDL が生成されるときに警告を受けるよう指定できます。

[PortType class] は、WSDL オペレーションに対応するプロシージャーを定義するクラスの名前です。これらのプロシージャーは、LotusScript ではパブリックの関数またはサブルーチン、Java ではパブリックのメソッドであることが必要です。プライベートの関数、サブルーチン、メソッドは、Web サービス・インターフェースを介しては公開されません。コーディングまたは WSDL のインポートによってクラスを作成するまでは、プロパティボックスの [PortType class] には入力できません。コードについては、後で詳しく説明します。

[セキュリティ] タブは、エージェントの [セキュリティ] タブとほとんど同じ内容です。セキュリティについては、後で詳しく説明します。

[詳細] タブには、Web サービスの定義と WSDL の生成に関する詳細情報が含まれています。この点についても、後で詳しく説明します。

プログラムペインもエージェントの場合と同様です。右側のドロップダウンボックスで、LotusScript または Java を選択できます。Java を選択したようすを下図に示します。左側には、[Objects] と [Reference] の各ペインがあります。

図 4. Web サービス (Java)
Web サービス (Java)

既存の WSDL 文書に基づいて新規の Web サービスを作成するときは、[Import WSDL] ボタンをクリックします。[Show WSDL] ボタンをクリックすると、Web サービスの変更内容がコンパイルされ、そのパブリック・インターフェースを定義する WSDL 文書が表示されます。[Export WSDL] ボタンをクリックすると、Web サービスの変更内容がコンパイルされ、そのパブリック・インターフェースを定義する WSDL 文書がエクスポートされます。また、Web サービスを保存または閉じることによっても、コンパイルが行われます。パブリック・インターフェースが変更されると、WSDL が再生成されます。
 
上に戻る
 
基本的なコーディング
Web サービスのコードは、次の要素で構成されています。
  • 実装コードのクラス定義。このクラスは、プロパティボックスの [基本] タブの [PortType class] で付けられた名前と一致し、パブリックでなければなりません。
  • クラス内における、Web サービスの各オペレーション用のプロシージャー (関数、サブルーチン、またはメソッド) 定義。これらのプロシージャーはパブリックであることが必要です。サポートするプロシージャーでインターフェース内に置かないものは、プライベートにします。
  • LotusScript 用の lsxsd.lss のインクルード、および Java 用の lotus.domino.types.* のインポート。
  • Domino Object にアクセスする場合は、NotesSession オブジェクト (LotusScript) または Session オブジェクト (Java) の初期化。初期化を行う場所としては、LotusScript の場合は new ブロック、Java の場合はパラメーターを持たないコンストラクターが最適です。Java では、WebServiceBase.getCurrentSession() を使用して Session オブジェクトを取得していました。Session.getAgentContext() で AgentContext オブジェクトを取得できると便利です。しかし、WebServiceBase は JavaAgent と等価ですが、Web サービスはこのオブジェクトへはアクセスできません。このため、使用できるメソッドは、static getCurrentSession() だけです。

LotusScript コード用のテンプレートを以下に示します。このテンプレートの Web サービスには、1 つのオペレーションがあります。このオペレーションは、先ほどの例に用いたもので、3 つの入力パラメーターと 1 つの戻り値を持ちます。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject
 Sub NEW
  Set s = New NotesSession
 End Sub
 Function getNthSubject(dbname As String, viewname As String, n As Long) As String
    ! Code for doing the operation goes here
 End Function
End Class

次に、Java コード用のテンプレートを示します。このテンプレートでは、Web サービスに 1 つのオペレーションが含まれます。コンストラクターには、デフォルトのコンストラクター (パラメーターなし) を使用してください。それ以外のコンストラクターは無視されます。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {
 Session s;
 public GetSubject() {
  s = WebServiceBase.getCurrentSession();
 }
 public String getNthSubject(String dbname, String viewname, int n) {
    // Code for doing operation goes here
 }
}

それでは、サンプルを拡張して処理コードを含めます。LotusScript コードは次のようになります。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject

 Sub NEW
  Set s = New NotesSession
 End Sub

 Function getNthSubject(dbname As String, viewname As String, n As Long) As String
  Dim db As NotesDatabase
  Dim view As NotesView
  Dim doc As NotesDocument
  Set db = s.GetDatabase("", dbname)
  If Not(db.IsOpen) Then
   getNthSubject = "Cannot open database " & dbname
   Exit Function
  End If
  Set view = db.GetView(viewname)
  If view Is Nothing Then
   getNthSubject = "Cannot open view " & viewname
   Exit Function
  End If
  Set doc = view.GetNthDocument(n)
  If doc Is Nothing Then
   getNthSubject = "Cannot get document " & n
   Exit Function
  End If
  If doc.HasItem("Subject") Then
   getNthSubject = doc.GetItemValue("Subject")(0)
  Else
   getNthSubject = "Document does not have Subject"
  End If
 End Function
End Class

Java コードは次のようになります。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {

 Session s;

 public GetSubject() {
  s = WebServiceBase.getCurrentSession();
 }
 public String getNthSubject(String dbname, String viewname, int n) {
  String subject = null;
  try {
   Database db = s.getDatabase(null, dbname);
   if (!db.isOpen()) subject = "Cannot open database " + dbname;
   else {
    View view = db.getView(viewname);
    if (view == null) subject = "Cannot open view " + viewname;
    else {
     Document doc = view.getNthDocument(n);
     if (doc == null) subject = "Cannot get document " + n;
     else {
       if (doc.hasItem("Subject"))
       subject = doc.getItemValueString("Subject");
      else subject = "Document does not have Subject";
     }
    }
   }
  }
  catch(Exception e) {
   subject = e.toString();
   e.printStackTrace();
  }

  return subject;
 }
}
 
上に戻る
 
Web サービスの呼び出しとテスト
最終的に、Web サービス設計要素は、HTTP が実行されている Domino 7 Server に配置する必要があります。しかし、Domino Designer にある Web サービス設計要素は、テストすることができます。テストを行うには、HTTP を起動させる任意の要素 (たとえば、フォームなど) で [設計] - [Web ブラウザでのプリビュー] を選択します。コンシューマーが Notes Client と同じマシン上にある場合は、コンピュータ・アドレスとして「127.0.0.1」を使用します。Web サービスのコンシューマーとして動作するには、HTTP POST リクエストで SOAP メッセージを Domino Web サービスの URL に送信する必要があります。URL は次のようになります。

http://rperron300pl.notesdev.ibm.com/Webservices2.nsf/GetSubject? OpenWebService

SOAP メッセージは次のようになります。

<SOAP-ENV:Envelope
 ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 <SOAP-ENV:Body>
  <ns0:getNthSubject (1)
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:ns0="urn:DefaultNamespace">
  <dbname xsi:type="xsd:string">Webservices2</dbname> (2)
  <viewname xsi:type="xsd:string">Main View</viewname> (2)
  <n xsi:type="xsd:int">2</n> (2)
 </ns0:getNthSubject>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

このサンプルでは、SOAP メッセージは、(1) オペレーションを識別し、(2) 入力パートに値を提供しています。SOAP-ENV:body に表示される特定の要素は、WSDL バインディング特性、特に SOAP メッセージ形式によって決められます (詳細については、以降の「詳細プロパティ」を参照してください)。

WebSphere SDK for Web Services には、Web サービスを呼び出し、その結果を表示するツールがあります。この SDK は Eclipse のもとで動作します。次のものがインストールされていなければなりません。
この記事を書いている時点では、WebSpere SDK は Eclipse 3.0 では動作しません。また、WebSphere Studio Application Developer(現在リンク切れ)を使用することによっても Web サービスを呼び出すことができます。最新バージョンは v5.1.2 です。

WebSphere SDK ツールを使用するには、Eclipse を起動し、[実行] - [Launch the Web Services Explorer] を選択します。Web Services Explorer がロードした後、次のように操作します。

  1. [WSDL Page] アイコンをクリックします。これは、右上の右矢印から 3 番目のアイコンです。左側の [Navigator] ペインに、[WSDL Main] リンクが表示されます。

  2. [WSDL Main] リンクをクリックします。右側のペインに [Open WSDL] ボックスが表示されます。

  3. /WSDL コマンドを付けて Web サービスの URL を入力し(例: http://rperron300pl.notesdev.ibm.com/Webservices2.nsf/GetSubject? WSDL)、[Go] をクリックします。Web Services Explorer がこの時点で WSDL 文書を読み込むので、/OpenWebService ではなく /WSDL が必要になります。

  4. 右側のペインに [WSDL Binding Details] ボックスが表示されます。これには、 Web サービスによって定義されたオペレーションへのリンクが含まれています。

  5. オペレーションの名前 (例: getNthSubject) をクリックします。[Invoke a WSDL Operation] ボックスが表示されます。

  6. オペレーションの名前 (例: getNthSubject) をクリックします。[Invoke a WSDL Operation] ボックスが表示されます。

レスポンスは、一番下のペイン (Status) に戻されます。サンプルの Web サービスを呼び出した後の Web Services Explorer を下図に示します。

図 5. Web Services Explorer
Web Services Explorer

[Actions] ボックスの右上に [Source] リンクがあります。[Source] をクリックすると、実際の SOAP メッセージが表示されます。SOAP メッセージを変更し、[Go] をクリックすることで転送できます。右上の [Form] をクリックすると、元の表示に戻ります。[Status] ボックスにも [Source] リンクがあり、このリンクをクリックすると SOAP レスポンスが表示されます。[Status] に表示するものがない (さらに、レスポンスが必要) と表示された場合は、コードが失敗した可能性があります。

Web サービスの実行後は、サーバーコンソールまたは log.nsf でエラーメッセージをチェックします。サーバーコンソールまたは log.nsf に出力する MessageBox ステートメントを挿入することにより、ログを記録したり、デバッグを行うことができます。(Beta 2 では、Print ステートメントは使用しないでください。このステートメントはエージェントでは HTTP ストリームに入り、SOAP レスポンスと競合するからです。)
 
上に戻る
 
詳細プロパティ
プロパティボックスの [詳細] タブは、WSDL 文書に反映される際に Web サービスの定義に影響します。

図 6. [Web Services] プロパティボックスの [詳細] タブ
[Web Services] プロパティボックスの [詳細] タブ

このタブでは、ポートタイプ、サービス要素、およびサービスポートのそれぞれの名前を指定できます。たとえば、すべての名前を GetSubject にすることができます。また、より明確にするために、要素のタイプを示す接尾辞を付けることもできます。プロパティボックスで名前を指定すると、生成される WSDL 文書にこれらの名前が書き込まれます。WSDL 文書をインポートする場合は、WSDL 文書で定義された名前が、自動的にプロパティボックスへ書き込まれます。

GetSubject サンプルの WSDL 文書全体を以下に示します。注釈で示した箇所が、[Web Services] プロパティボックスの [詳細] タブの値が反映されている部分です。

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:DefaultNamespace"
xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="urn:DefaultNamespace" xmlns:intf="urn:DefaultNamespace"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <wsdl:message name="getNthSubjectResponse">
  <wsdl:part name="getNthSubjectReturn" type="xsd:string"/> (6)
 </wsdl:message>
 <wsdl:message name="getNthSubjectRequest">
 <wsdl:part name="dbname" type="xsd:string"/> (6)
 <wsdl:part name="viewname" type="xsd:string"/> (6)
 <wsdl:part name="n" type="xsd:int"/> (6)
</wsdl:message>
 <wsdl:portType name="GetSubjectPortType"> (1)
  <wsdl:operation name="getNthSubject"
    parameterOrder="dbname viewname n">
  <wsdl:input message="impl:getNthSubjectRequest"
          name="getNthSubjectRequest"/>
  <wsdl:output message="impl:getNthSubjectResponse"
          name="getNthSubjectResponse"/>
  </wsdl:operation>
 </wsdl:portType>
  <wsdl:binding name="GetSubjectPortSoapBinding"
        type="impl:GetSubjectPortType">
 <wsdlsoap:binding style="rpc" (4)
        transport="http://schemas.xmlsoap.org/soap/http"/>
 <wsdl:operation name="getNthSubject">
  <wsdlsoap:operation soapAction=""/> (7)
  <wsdl:input name="getNthSubjectRequest">
   <wsdlsoap:body
   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" (5)
   namespace="urn:DefaultNamespace" use="encoded"/> (5)
 </wsdl:input>
  <wsdl:output name="getNthSubjectResponse">
   <wsdlsoap:body
    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" (5)
    namespace="urn:DefaultNamespace" use="encoded"/> (5)
  </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="GetSubjectElement"> (2)
  <wsdl:port binding="impl:GetSubjectPortSoapBinding"
        name="GetSubjectPort"> (3)
   <wsdlsoap:address location="http://localhost"/>
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

(1)ポートタイプは、オペレーションのセットを定義します。WSDL 文書には、詳細プロパティの [Port type name] に対応する wsdl:portType の name 属性があります。

(2)サービスは、サポートされているポートを識別します。WSDL 文書には、詳細プロパティの [Service element name] に対応する wsdl:service の name 属性があります。WSDL のエクスポート、WSDL の表示、または Domino Designer でのブラウザのプリビューを介して WSDL を取得した場合は、wsdlsoap:address の location 属性は正しくありません。この属性は、?WSDL URL コマンドを介してサーバーから取得したときに、正しい値が得られます。

(3)ポートはバインディングを識別します。バインディングはポートタイプを識別し、追加情報を提供します。WSDL 文書では、wsdl:service の下に wsdl:port の name 属性があります。Domino では、1 つのサービスごとに 1 つのポートが認められます。

(4)2 つのプログラミング・モデルと 4 つの SOAP メッセージ形式を利用できます。RPC プログラミング・モデルでは、RPC/encoded、RPC/literal、Doc/literal、および Wrapped の 4 つの SOAP メッセージ形式を使用できます (5 番目の形式である Doc/encoded の使用方法が不明なため、ここではこの形式はサポートしません)。メッセージ・プログラミング・モデルでは、Doc/literal メッセージ形式が強制的に使用されます。しかし、単にヒントとしての説明ですが、メッセージ・ベースの Web サービスで実際に渡される SOAP メッセージ形式は発行されておらず、コンシューマーとプロバイダー間のプライベートなやり取りによって決められます。

wsdlsoap:binding の style 属性は次のように設定されます。
  • wsdlsoap:binding style="rpc" (RPC/encoded と RPC/literal の場合)
  • wsdlsoap:binding style="document" (Doc/literal と Wrapped の場合)

(5)wsdl:binding の下の input 要素と output 要素では、wsdlsoap:body の use 属性は次のように設定されます。
  • wsdlsoap:body use="encoded" (RPC/encoded の場合)この場合は、encodingStyle 属性があります。
  • wsdlsoap:body use="literal" (RPC/literal、Doc/literal、および Wrapped の場合)この場合は、encodingStyle 属性はありません。

(6)RPC/encoded と RPC/literal の場合、各 message パートは、XMLSchema ネームスペース (例: type="xsd:string" または type="xsd:int") を直接参照するか、WSDL の "types" セクション (この例では表示されていません) で定義された複合データ型を直接参照することによりデータ型を定義します。

Doc/literal の場合、各 message パートは前に定義されたデータ要素を参照します。Doc/literal が指定されたサンプルの WSDL からの抜粋を以下に示します。wsdl:types では、各入力パートは、プロシージャー・コード内の対応するパラメーターと同じ名前の要素内で定義されます。また、出力パートは、プロシージャー名に「Return」を追加した名前の要素内で定義されます。

<wsdl:types>
 <schema targetNamespace="urn:DefaultNamespace"
     xmlns="http://www.w3.org/2001/XMLSchema">
  <element name="dbname" type="xsd:string"/>
  <element name="viewname" type="xsd:string"/>
  <element name="n" type="xsd:int"/>
  <element name="getNthSubjectReturn" type="xsd:string"/>
 </schema>
</wsdl:types>
<wsdl:message name="getNthSubjectResponse">
 <wsdl:part element="impl:getNthSubjectReturn"
       name="getNthSubjectReturn"/>
</wsdl:message>
<wsdl:message name="getNthSubjectRequest">
  <wsdl:part element="impl:dbname" name="dbname"/>
  <wsdl:part element="impl:viewname" name="viewname"/>
  <wsdl:part element="impl:n" name="n"/>
</wsdl:message>

Wrapped の場合、各メッセージには、前に定義された complexType 型の要素を参照する 1 つのパートがあります。この要素は、それを使用するオペレーションと同じ名前が付けられ、属性は持ちません。Wrapped が指定された WSDL の抜粋を以下に示します。

<wsdl:types>
 <schema targetNamespace="urn:DefaultNamespace"
     xmlns="http://www.w3.org/2001/XMLSchema">
 <element name="getNthSubject">
  <complexType>
   <sequence>
    <element name="dbname" type="xsd:string"/>
    <element name="viewname" type="xsd:string"/>
   <element name="n" type="xsd:int"/>
   </sequence>
  </complexType>
 </element>
 <element name="getNthSubjectResponse">
  <complexType>
  <sequence>
   <element name="getNthSubjectReturn" type="xsd:string"/>
   </sequence>
  </complexType>
  </element>
 </schema>
</wsdl:types>
<wsdl:message name="getNthSubjectResponse">
 <wsdl:part element="impl:getNthSubjectResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getNthSubjectRequest">
 <wsdl:part element="impl:getNthSubject" name="parameters"/>
</wsdl:message>

SOAP 形式の詳細な解説については、developerWorks の記事『Which style of WSDL should I use?(英語)』を参照してください。

(7)[Include operation name in SOAP action] オプションをオフにすると、soapAction="" になります。このオプションをオンにすると、soapAction はオペレーションの名前を指定します。例を以下に示します。

<wsdlsoap:operation soapAction="getNthSubject"/>
 
上に戻る
 
セキュリティ
Web サービスのセキュリティは、Web から呼び出されるサーバーエージェントのセキュリティに似ています。[Web Services] プロパティボックスの [セキュリティ] タブの例を以下に示します。

図 7. [Web Services] プロパティボックスの [セキュリティ] タブ
[Web Services] プロパティボックスの [セキュリティ] タブ

最初の 2つの行で、Web サービスを実行するユーザー、つまり有効なユーザーを指定します。どちらの行も指定されない場合は、Web サービスの所有者 (設計要素を最後に編集または署名したユーザー) が有効なユーザーとなります。
  • [Run as Web user] オプションが選択された場合は、Web サービスが保存されているデータベースへのネットワークアクセスを確立したユーザーが有効なユーザーとなります。つまり、データベースで匿名アクセスが許可されている場合は「Anonymous」で、それ以外の場合は認証プロセスで提供されたユーザー名です。
  • [Run on behalf of] フィールドに入力されている場合は、入力されたユーザーが有効なユーザーです。

Web サービスのコンシューマーは、サーバーへのアクセスを確立しなければなりません。HTTP ポートで匿名アクセスが許可されている場合は、アクセスは自動で行われます。それ以外の場合は、コンシューマーは有効な名前とインターネットパスワードを使用して認証を受ける必要があります。有効なユーザーには、データベースの ACL で、[パブリック文書 [読者]] 権限を持つ [投稿者] 以上のアクセス権を付与します。

[Compile Java code with debugging information] オプションをオンにすると、JPDA (Java Platform Debugger Architecture) をサポートする Eclipse などの Java デバッガから、実行中の Web サービスにアクセスできます。Java デバッグはリリース 7 の新機能で、Notes Client でのみ機能します。デバッグを行うには、Web サービスが Notes Client 上に存在しなければなりません。まず、任意の設計要素で [設計] - [Web ブラウザでのプリビュー] を選択し、クライアントで HTTP タスクを開始させます。次に、Web サービスを呼び出します。Web サービスには、動作を一時的に停止させるデバッグ専用のコードを含める必要があります。そして、実行中の Web サービスにデバッガを接続します。

LotusScript による Web サービスの場合は、Java デバッグの行に [リモートデバッグを許可] が表示されます。Web サービスのリモートデバッグは、エージェントの場合と同じです。リモートデバッグを行うには、Web サービスがサーバーに置かれている必要があります。

[Profile this Web service] をオンにすると、Domino Object によって使用された経過時間の合計が得られます。選択した Web サービスについての結果をレポートするには、[設計] - [View Profile Results] を選択します。プロファイリングはリリース 7 の新機能で、LotusScript または Java でコーディングされたエージェントと Web サービスに使用できます。

[実行時セキュリティレベルの設定] ボックスでは、3 段階のセキュリティレベルを指定できます。セキュリティレベルの数値が大きいほど、ファイルシステムへの書き込みや環境変数の操作など、潜在的な危険性の高いオペレーションが可能になります。

[Default access to this Web service] では、[読者] 以上のアクセス権を持つすべてのユーザーにアクセスを許可するか、アクセスを付与するユーザーを個別に指定します。
 
上に戻る
 
Web サービスのコンテキスト
Web サービスはエージェントと同じフレームワークを使用します。バックエンドでは、ほとんどの (ただし、すべてではない) エージェントコンテキストが Web サービスに適用されます。Java で Session オブジェクトと AgentContext オブジェクトを取得する方法、および LotusScript で NotesSession オブジェクトを取得する方法については、すでに説明してきました。ここでは、それ以外の要素として、Web サービスに対応するコンテキスト関連の主な要素について説明します。

コンテキスト関連要素 Java LotusScript
現在の Web サービス AgentContext.getCurrentAgent(); NotesSession.CurrentAgent
現在のデータベース AgentContext.getCurrentDatabase(); NotesSession.CurrentDatabase
サーバーコンソールおよび log.nsf への出力 System.out Messagebox
Web サービスの名前と別名 Agent.getName(); NotesAgent.Name
Web サービスの所有者 (フルネーム) Agent.getOwner(); NotesAgent.Owner
Web サービスの所有者 (共通名) Agent.getCommonOwner(); NotesAgent.CommonOwner
Web サービスのランタイムの所有者 Agent.getOnBehalfOf(); NotesAgent.OnBehalfOf
Web サービスのコメント Agent.getComment(); NotesAgent.Comment
Web サービスの HTTP URL Agent.getHttpURL(); NotesAgent.HttpURL
Web サービスの Notes URL Agent.getNotesURL(); NotesAgent.NotesURL
Web の親データベース Agent.getParent(); NotesAgent.Parent
Web サービスのロック獲得者 Agent.getLockHolders(); NotesAgent.LockHolders

Web サービス設計要素は、エージェントと同様にロックまたはロック解除することができます。

Web サービスのコンテキストに関連するプロパティを取得する LotusScript のサンプルを以下に示します。この Web サービスには、3 つのオペレーションがあります。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Dim agent As NotesAgent
Class GetAgentContext

 Sub NEW
  Set s = New NotesSession
  Set agent = s.CurrentAgent
 End Sub

 Function getAgentName() As String
  getAgentName = agent.Name
 End Function

 Function getEffectiveUserName() As String
  getEffectiveUserName = s.EffectiveUserName
 End Function

 Function getDatabaseFileName() As String
  Dim db As NotesDatabase
  Set db = s.CurrentDatabase
  getDatabaseFileName = db.FileName
 End Function

End Class

Java コードは次のようになります。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetAgentContext {

 Session s;
 AgentContext ac;

 public GetAgentContext() {
  s = WebServiceBase.getCurrentSession();
  try {
   ac = s.getAgentContext();
  } catch(Exception e) {
   e.printStackTrace(); }
 }
 public java.lang.String getAgentName() {
  String agentName = null;
  try {
   Agent agent = ac.getCurrentAgent();
   agentName = agent.getName(); }
  catch(Exception e) {
   e.printStackTrace(); }
  return agentName;
 }
 public java.lang.String getEffectiveUserName() {
  String userName = null;
  try {
   userName = ac.getEffectiveUserName(); }
  catch(Exception e) {
   e.printStackTrace(); }
  return userName;
 }
 public java.lang.String getCurrentDatabase() {
  String dbFileName = null;
  try {
   Database db = ac.getCurrentDatabase();
   dbFileName = db.getFileName(); }
  catch(Exception e) {
   e.printStackTrace(); }
  return dbFileName;
 }
}
 
上に戻る
 
複合データ型
次のモデルを使用するオペレーションは、複合データ型を必要としません。
  • 単一のスカラー出力値 (または出力値なし)
  • スカラー入力値 (または入力値なし)

複数のスカラー出力値を返すオペレーションまたは複数のスカラー入力値を受け取るオペレーションには、複合データ型が必要です。複合データ型を使用すると、さまざまな種類の大きなデータ構造体を移動することができます。

次のセクションでは、以下に示す複合データ型について説明します。
  • 配列
  • クラス
  • 入出力パラメーターと出力パラメーター

配列
配列は complexType WSDL 要素に対応し、その名前は ArrayOf にデータ型の接尾辞を追加したものになります。WSDL は complexType 要素を配列として定義します。

たとえば、Java メソッドとして実装された次のオペレーションは、String 配列を返します。

public java.lang.String[] getAll() {
 String[] info = new String[3];
 try {
  info[0] = ac.getEffectiveUserName();
  info[1] = s.getPlatform();
  info[2] = s.getNotesVersion(); }
 catch(Exception e) {
  e.printStackTrace(); }
 return info;
}

Java の String 配列は WSDL complexType 要素に対応し、名前は ArrayOf_xsd_string です。これは、ストリング型の配列として定義されます。getAll オペレーションの戻り値を定義するメッセージ (getAllResponse) は 1 つのパートを持ち、このパートの型は ArrayOf_xsd_string です。

- <wsdl:types>
 - <schema targetNamespace="urn:DefaultNamespace"
   xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
  - <complexType name="ArrayOf_xsd_string">
   - <complexContent>
    - <restriction base="soapenc:Array">
      <attribute ref="soapenc:arrayType"
       wsdl:arrayType="xsd:string[]" />
      </restriction>
     </complexContent>
    </complexType>
   </schema>
  </wsdl:types>
- <wsdl:message name="getAllResponse">
  <wsdl:part name="getAllReturn" type="impl:ArrayOf_xsd_string" />
 </wsdl:message>

LotusScript では、Web サービスのコンシューマーに配列を返すことはできません。言語の規則によって、配列の戻り値は Variant 型で定義する必要があります。しかし、Variant 型では、WSDL 生成時に型を変換するための十分な情報が得られません。この対策としては、次に示すように、配列をクラス内に配置します。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class infoArray
 Public info() As String
End Class
Class GetSessionInfo
 Sub NEW
  Set s = New NotesSession
 End Sub

 Function getItAll() As infoArray
  Set getItAll = New infoArray
  Redim getItAll.info(1 To 3)
  getItAll.info(1) = s.EffectiveUserName
  getItAll.info(2) = s.Platform
  getItAll.info(3) = s.NotesVersion
 End Function
End Class

クラス
クラスは complexType WSDL 要素に対応し、要素の名前はクラス名と同じです。配列の例と同じデータを提供する Java のサンプルを以下に示します。ただし、このサンプルでは、配列を返さずに、1 つのオブジェクトを返します。

public InfoClass getAll2() {
 InfoClass info = new InfoClass();
 try {
  info.effectiveUserName = ac.getEffectiveUserName();
  info.platform = s.getPlatform();
  info.notesVersion = s.getNotesVersion(); }
 catch(Exception e) {
  e.printStackTrace(); }
 return info;
}
public class InfoClass {
 public String effectiveUserName;
 public String platform;
 public String notesVersion;
}

Java クラスの InfoClass は、同じ名前の complexType に対応します。complexType は 3 つの要素を持ちます。各要素の型は xsd:string で、Java の InfoClass クラス内でのパブリック・データ要素に合わせて名前が付けられます。

- <wsdl:types>
 - <schema targetNamespace="urn:DefaultNamespace"
   xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
  - <complexType name="InfoClass">
   - <sequence>
     <element name="notesVersion"
      nillable="true" type="xsd:string" />
     <element name="platform"
      nillable="true" type="xsd:string" />
     <element name="effectiveUserName"
      nillable="true" type="xsd:string" />
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>
- <wsdl:message name="getAll2Response">
  <wsdl:part name="getAll2Return" type="impl:InfoClass" />
 </wsdl:message>

同じ内容を LotusScript で記述すると、次のようになります。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class InfoClass
 Public EffectiveUserName As String
 Public Platform As String
 Public NotesVersion As String
End Class
Class GetSessionInfo
 Sub NEW
  Set s = New NotesSe
ssion  End Sub

 Function getItAll2() As InfoClass
  Set getItAll2 = New InfoClass
  getItAll2.EffectiveUserName = s.EffectiveUserName
  getItAll2.Platform = s.Platform
  getItAll2.NotesVersion = s.NotesVersion
 End Function
End Class

入出力パラメーターと出力パラメーター
出力メッセージが 1 つのパートを持つとき、それが単一型か複合型かにかかわらず、出力は関数またはメソッドの戻り値に対応します。出力メッセージが複数のパートを持つときは、出力は戻り値と共にパラメーターにも対応するか、戻り値の代わりにパラメーターに対応します。正確な対応は、入力パートと、それが出力パートとどのように組み合わせられるかによって決められます。最初の出力パートがどの入力パートとも一致せず、残りの出力パートが入力パートに一致する場合は、最初の出力パートが関数またはメソッドの戻り値に対応し、残りのパートは入出力パラメーターに対応します。

それ以外の場合は、一致する入力パートと出力パートは入出力パラメーターに対応し、一致しない入力パートは入力パラメーターに対応します。さらに、一致しない出力パートは、出力パラメーターに対応します。この場合、戻り値はなく、LotusScript では関数の代わりにサブルーチンが使用されます。

次に示す WSDL の抜粋は最初のサンプルを変更したもので、レスポンスとして入力値を送り返します。

- <wsdl:message name="getNthSubjectResponse">
  <wsdl:part name="getNthSubjectReturn" type="xsd:string" />(1)
  <wsdl:part name="dbname" type="xsd:string" />(2)
  <wsdl:part name="viewname" type="xsd:string" />(3)
  <wsdl:part name="n" type="xsd:int" />(4)
 </wsdl:message>
- <wsdl:message name="getNthSubjectRequest">
  <wsdl:part name="dbname" type="xsd:string" />(2)
  <wsdl:part name="viewname" type="xsd:string" />(3)
  <wsdl:part name="n" type="xsd:int" />(4)
 </wsdl:message>

(1)1 つの出力パート (getNthSubjectReturn) は入力パートに一致しません。このパートは、関数またはメソッドの戻り値に対応します。

(2)(3)(4)残りの 3 つの出力パート (dbname、viewname、n) は、3 つの入力パートと同じです。したがって、これらのパートは 3 つの入出力パラメーターに対応します。

入出力パラメーターと出力パラメーターは、プリミティブ・データ型にすることはできません。標準の Java では、さまざまな型の入出力パラメーターと出力パラメーターを保持するメソッドが含まれる javax.xml.rpc.holders パッケージが提供されています。Lotus Domino では、下表に示すように、入出力パラメーターと出力パラメーターをこれらのクラスに対応させています。

BigDecimalHolder CalendarHolder LongHolder
BigIntegerHolder DoubleHolder LongWrapperHolder
BooleanHolder oubleWrapperHolder ObjectHolder
BooleanWrapperHolder FloatHolder QNameHolder
ByteArrayHolder FloatWrapperHolder ShortHolder
ByteHolder IntegerWrapperHolder ShortWrapperHolder
ByteWrapperHolder IntHolder StringHolder

これらのクラスは、アプリケーション・コードを取得または設定できる「value」という名前のパブリック変数を持ちます。次に示すサンプルは、String を返すこれまでの getNthSubject を変更したものです。変更後は、StringHolder クラスと IntHolder クラスを使用して 3 つのパラメーターを入出力に使用しています。パラメーターの値は、SOAP レスポンスに含められてコンシューマーに送り返されます。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {

 Session s;

 public GetSubject() {
  s = WebServiceBase.getCurrentSession();
 }
 public String getNthSubject(javax.xml.rpc.holders.StringHolder dbname,
   javax.xml.rpc.holders.StringHolder viewname,
   javax.xml.rpc.holders.IntHolder n) {
  String subject = null;
  try {
   Database db = s.getDatabase(null, dbname.value);
   if (!db.isOpen()) subject = "Cannot open database " + dbname.value;
   else {
    View view = db.getView(viewname.value);
    if (view == null) subject = "Cannot open view " + viewname.value;
    else {
     Document doc = view.getNthDocument(n.value);
     if (doc == null) subject = "Cannot get document " + n.value;
     else {
       if (doc.hasItem("Subject"))
       subject = doc.getItemValueString("Subject");
      else subject = "Document does not have Subject";
     }
    }
   }
  }
  catch(Exception e) {
   e.printStackTrace();
  }

  return subject;
 }
}

LotusScript では、インクルード・ファイルの lsxsd.lss において、入出力パラメーターと出力パラメーター用の次のホルダー・クラスが定義されています。

BOOLEAN_HOLDER LONG_HOLDER
BOOLEANARRAY_HOLDER LONGARRAY_HOLDER
BYTE_HOLDER SINGLE_HOLDER
BYTEARRAY_HOLDER SINGLEARRAY_HOLDER
DOUBLE_HOLDER STRING_HOLDER
DOUBLEARRAY_HOLDER STRINGARRAY_HOLDER
INTEGER_HOLDER VARIANT_HOLDER
INTEGERARRAY_HOLDER VARIANTARRAY_HOLDER

これらのクラスは、アプリケーション・コードを取得または設定できる「Value」という名前のパブリック変数を持ちます。次の LotusScript のサンプルは、前に示した Java のサンプルと同じ内容です。3 つの入出力パラメーター用にホルダー・クラスが使用されています。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject

 Sub NEW
  Set s = New NotesSession
 End Sub

 Function getNthSubject(dbname As String_Holder, _
 viewname As String_Holder, _
 n As Long_Holder) As String
  Dim db As NotesDatabase
  Dim view As NotesView
  Dim doc As NotesDocument
  Set db = s.GetDatabase("", dbname.Value)
  If Not(db.IsOpen) Then
   getNthSubject = "Cannot open database " & _
     dbname.Value
   Exit Function
  End If

  Set view = db.GetView(viewname.Value)
  If view Is Nothing Then
   getNthSubject = "Cannot open view " & _
      viewname.Value
   Exit Function
  End If
  Set doc = view.GetNthDocument(n.Value)
  If doc Is Nothing Then
   getNthSubject = "Cannot get document " & _
     n.Value
   Exit Function
  End If
  If doc.HasItem("Subject") Then
   getNthSubject = doc.GetItemValue("Subject")(0)
  Else
   getNthSubject = "Document does not have Subject"
  End If
 End Function

End Class
 
上に戻る
 
データ型の対応
プリミティブ・データ型と XSD でそれに対応する型は、一般的に、相互に対応しています。インポートされた SOAPENC データ型は例外で、これは 1 つのオブジェクトに対応します。しかし、生成された WSDL への出力では、オブジェクトは XSD データ型に対応します。

インポートされた WSDL Java データ型
LotusScript データ型
生成された WSDL
xsd:boolean boolean Boolean xsd:boolean
soapenc:boolean java.lang.Boolean XSD_BOOLEAN(1) xsd:boolean
xsd:byte byte XSD_BYTE(2) xsd:byte
soapenc:byte java.lang.Byte XSD_BYTE xsd:byte
xsd:double double Double xsd:double
soapenc:double java.lang.Double XSD_DOUBLE xsd:double
xsd:float float Single xsd:float
soapenc:float java.lang.Float XSD_FLOAT xsd:float
xsd:int int Long xsd:int
soapenc:int java.lang.Integer XSD_INT xsd:int
xsd:long long XSD_LONG(3) xsd:long
soapenc:long java.lang.Long XSD_LONG xsd:long
xsd:short short Integer xsd:short
soapenc:short java.lang.Short XSD_SHORT xsd:short
xsd:string java.lang.String(4)String xsd:string
soapenc:string java.lang.String XSD_STRING xsd:string

(1)Java では、java.lang.Boolean、java.lang.Byte、など java.lang で定義されたラッパー・クラスが使用されます。LotusScript では、XSD_BOOLEAN、XSD_BYTE など lsxsd.lss で定義された XSD_ クラスが使用されます。LotusScript のクラスは次のメソッドを継承します。

Function GetValueAsString() As String
Sub SetValueAsString(value As String)

メモ:次回の Beta リリースでは、SetValueAsString という名前は SetValueFromString に変わる予定です。

次の Java コードは、java.lang.Boolean 型を返すオペレーションのサンプルです。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetDatabaseInfo {

 Session s;
 AgentContext ac;
 Database db;

 public GetDatabaseInfo() {
  s = WebServiceBase.getCurrentSession();
  try {
   ac = s.getAgentContext();
   db = ac.getCurrentDatabase();
  } catch(Exception e) {
   e.printStackTrace(); }
 }
 public Boolean doesViewExist(String viewName) {
  Boolean b = null;
  try {
   if (db.getView(viewName) == null)
    b = new Boolean(false);
   else
    b = new Boolean(true);
  } catch(Exception e) {
    e.printStackTrace(); }
  return b;
 }
}

対応する LotusScript のオペレーションは、XSD_BOOLEAN 型を返します。

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Dim db As NotesDatabase
Class GetDatabaseInfo

 Sub NEW
  Set s = New NotesSession
  Set db = s.CurrentDatabase
 End Sub

 Function DoesViewExist(viewName As String) As XSD_BOOLEAN
  Set b = New XSD_BOOLEAN
  If db.GetView(viewName) Is Nothing Then
   Call b.SetValueAsString("False")
  Else
   Call b.SetValueAsString("True")
  End If
   Set DoesViewExist = b
 End Function
 
End Class

(2)LotusScript では、xsd:byte にはプリミティブを使用しません。これは、常に XSD_BYTE に対応します (LotusScript のプリミティブは xsd:unsignedByte に対応します)。

(3)LotusScript では、xsd:long にはプリミティブを使用しません。これは、常に XSD_LONG に対応します (LotusScript のプリミティブは xsd:int に対応します)。

(4)Java には xsd:string に対応するプリミティブはありません。これは、常に java.lang.String に対応します。

その他の XSD データ型は、Java では、java.lang、java.math、java.util、および lotus.domino.types (Lotus Notes/Domino 7 での新機能) の各オブジェクトに対応し、LotusScript では XSD_ オブジェクトに対応します。

WSDL Java データ型 LotusScript データ型
xsd:anyType java.lang.Object XSD_ANYTYPE Variant(1)
xsd:anyURI lotus.domino.types.URI XSD_ANYURI
xsd:base64Binary soapenc:base64(2) byte[]
xsd:date java.util.Date XSD_DATE
xsd:dateTime java.util.Calendar XSD_DATETIME
xsd:decimal soapenc:decimal(3) java.math.BigDecimal XSD_DECIMAL
xsd:duration lotus.domino.types.Duration XSD_DURATION
xsd:ENTITY lotus.domino.types.Entity XSD_ENTITY
xsd:ENTITES lotus.domino.types.Entities XSD_ENTITIES
xsd:gDay lotus.domino.types.GDay XSD_GDAY
xsd:gMonth lotus.domino.types.GMonth XSD_GMONTH
xsd:gMonthDay lotus.domino.types.GMonthDay XSD_GMONTHDAY
xsd:gYear lotus.domino.types.GYear XSD_GYEAR
xsd:gYearMonth lotus.domino.types.GYearMonth XSD_GYEARMONTH
xsd:hexBinary lotus.domino.types.HexBinary XSD_HEXBINARY
xsd:ID lotus.domino.types.Id XSD_ID
xsd:IDREF lotus.domino.types.IDRef XSD_IDREF
xsd:IDREFS lotus.domino.types.IDRefs XSD_IDREFS
xsd:integer soapenc:integer(3) java.math.BigInteger XSD_INTEGER
xsd:language lotus.domino.types.Language XSD_LANGUAGE
xsd:Name lotus.domino.types.Name XSD_NAME
xsd:NCName lotus.domino.types.NCName XSD_NCNAME
xsd:negativeInteger lotus.domino.types.NegativeInteger XSD_NEGATIVEINTEGER
xsd:NMTOKEN lotus.domino.types.NMToken XSD_NMTOKEN
xsd:NMTOKENS lotus.domino.types.NMTokens XSD_NMTOKENS
xsd:nonNegativeInteger lotus.domino.types.NonNegativeInteger XSD_NONNEGATIVEINTEGER
xsd:nonPositiveInteger lotus.domino.types.NonPositiveInteger XSD_NONPOSITIVEINTEGER
xsd:NOTATION lotus.domino.types.Notation XSD_NOTATION
xsd:normalizedString lotus.domino.types.NormalizedString XSD_NORMALIZEDSTRING
xsd:positiveInteger lotus.domino.types.PositiveInteger XSD_NONPOSITIVEINTEGER
xsd:QName javax.xml.namespace.QName XSD_QNAME
xsd:time lotus.domino.types.Time XSD_TIME
xsd:token lotus.domino.types.Token XSD_TOKEN
xsd:unsignedByte lotus.domino.types.UnsignedByte Byte
XSD_UNSIGNEDBYTE(4)
xsd:unsignedInt lotus.domino.types.UnsignedInt XSD_UNSIGNEDINT
xsd:unsignedLong lotus.domino.types.UnsignedLong XSD_UNSIGNEDLONG
xsd:unsignedShort lotus.domino.types.UnsignedShort XSD_UNSIGNEDSHORT

(1)Variant は、生成された WSDL への出力で xsd:anyType に対応します。

(2)soapenc:base64 は、WSDL からのインポート時は byte[] と Byte に対応します。生成された WSDL は、常に xsd:base64Binary に対応します。

(3)soapenc:decimal と soapenc:integer は、WSDL からのインポート時は、XSD:DECIMAL と XSD:INTEGER に対応します。生成された WSDL は、常に xsd:decimal と xsd:integer に対応します。

(4)xsd:unsignedByte は、WSDL からのインポート時は Byte に対応します。生成された WSDL では、Byte と XSD_UNSIGNEDBYTE はどちらも xsd:unsignedByte に対応します。
 
上に戻る
 
プライベート・プロシージャー
Domino Web サービスは、実装クラス内のパブリックの関数、サブルーチン、およびメソッドを公開します。プライベート・プロシージャーは公開されません。次に示すのは、GetSubject サンプルの改訂版で、パブリック・プロシージャーを使用して、getFirstSubject、getLastSubject、および getNthSubject の各オペレーションを公開します。共通コードは、プライベート・プロシージャーの openDatabase、openView、および getSubject を介して提供されます。

Dim s As NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim msg As String
Class GetSubject

 Sub NEW
  Set s = New NotesSession
 End Sub

 Function getFirstSubject(dbname As String, viewname As String) As String
  If openDatabase(dbname) Then
   If openView(viewname) Then
    Set doc = view.GetFirstDocument
    If doc Is Nothing Then
     msg = "Cannot get first document "
    Else
     Call getSubject
    End If
   End If
  End If
  getFirstSubject = msg
 End Function
Function getLastSubject(dbname As String, viewname As String) As String
  If openDatabase(dbname) Then
   If openView(viewname) Then
    Set doc = view.GetLastDocument
    If doc Is Nothing Then
     msg = "Cannot get last document "
    Else
     Call getSubject
    End If
   End If
  End If
  getLastSubject = msg
 End Function

Function getNthSubject(dbname As String, viewname As String, n As Integer) As String
  If openDatabase(dbname) Then
   If openView(viewname) Then
    Set doc = view.GetNthDocument(n)
    If doc Is Nothing Then
     msg = "Cannot get document " & n
    Else
     Call getSubject
    End If
   End If
  End If
  getNthSubject = msg
 End Function

 Private Function openDatabase(dbname As String) As Boolean
  Set db = s.GetDatabase("", dbname)
  If db.IsOpen Then
   openDatabase = True
  Else
   openDatabase = False
   msg = "Cannot open database " & dbname
  End If
 End Function

 Private Function openView(viewname As String) As Boolean
  Set view = db.GetView(viewname)
  If view Is Nothing Then
   openView = False
   msg = "Cannot open view " & viewname
  Else
   openView = True
  End If
 End Function

 Private Sub getSubject
  If doc.HasItem("Subject") Then
   msg = doc.GetItemValue("Subject")(0)
  Else
   msg = "Document does not have Subject"
  End If
 End Sub

End Class

Java のサンプルを以下に示します。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {

 Session s;
 Database db;
 View view;
 Document doc;
 String msg;

 public GetSubject() {
  s = WebServiceBase.getCurrentSession();
 }
 public String getFirstSubject(String dbname, String viewname) {
  try {
   if (openDatabase(dbname)) {
    if (openView(viewname)) {
     doc = view.getFirstDocument();
     if (doc == null)
      msg = "Cannot get first document ";
     else
      getSubject();
    }
   }
  }
  catch(Exception e) {
   e.printStackTrace();
  }
  return msg;
 }
 public String getLastSubject(String dbname, String viewname) {
  try {
   if (openDatabase(dbname)) {
    if (openView(viewname)) {
     doc = view.getLastDocument();
     if (doc == null)
      msg = "Cannot get last document ";
     else
      getSubject();
    }
   }
  }
  catch(Exception e) {
   e.printStackTrace();
  }
  return msg;
 }
 public String getNthSubject(String dbname, String viewname, int n) {
  try {
   if (openDatabase(dbname)) {
    if (openView(viewname)) {
     doc = view.getNthDocument(n);
     if (doc == null)
      msg = "Cannot get document " + n;
     else
      getSubject();
    }
   }
  }
  catch(Exception e) {
   e.printStackTrace();
  }
  return msg;
 }
 private boolean openDatabase(String dbname) {
  boolean b = false;
  try {
   db = s.getDatabase(null, dbname);
   if (db.isOpen())
    b = true;
   else
    msg = "Cannot open database " + dbname;
  }
  catch(Exception e) {
    e.printStackTrace();
  }
  return b;
 }
 private boolean openView(String viewname) {
  boolean b = false;
  try {
   view = db.getView(viewname);
   if (view != null)
    b = true;
   else
    msg = "Cannot open view " + viewname;
  }
  catch(Exception e) {
   e.printStackTrace();
  }
  return b;
 }
 private void getSubject() {
  try {
   if (doc.hasItem("Subject"))
    msg = doc.getItemValueString("Subject");
   else
    msg = "Document does not have Subject";
  }
  catch(Exception e) {
    e.printStackTrace();
  }
 }

}
 
上に戻る
 
まとめ
Lotus Notes/Domino 7 では、Java または LotusScript でコーディングされ、エージェントに似た設計要素を介して Web サービスのプロバイダー側がサポートされます。Web サービスは、HTTP を有効にした Domino 7 Server に配置しなければなりません。ただし、Web プリビュー機能を利用すると、Notes Client 上で Web サービスをテストおよびデバッグすることができます。コンシューマーは、SOAP エンコードされた HTTP POST リクエストを介して Domino Web サービスにアクセスします。

Web サービスのオペレーションは、Java のパブリック・メソッド、および LotusScript のパブリック関数またはパブリック・サブルーチンに対応します。Web サービスのデータ・パートは、パラメーターと戻り値に対応します。XSD データ型は、可能な場合は Java と LotusScript のプリミティブに対応します。それ以外の場合は、complexType 要素がオブジェクトに対応します。

この記事は、Lotus Notes/Domino 7 の Beta 2 リリースに基づいて書かれています。開発プロセスで、機能拡張が行われる可能性もあります。たとえば、将来のリリースとして、Web サービスのコードをスクリプトライブラリに保存可能にするような計画もあります。
 
上に戻る
 
リソース
Lotus Domino は、SOAP 1.1 と WSDL 1.1 をサポートします。仕様および背景の情報については、次の W3C 文書を参照してください。
SOAP 形式の詳細な解説については、developerWorks の記事『Which style of WSDL should I use?(US)』を参照してください。

developerWorks ブログ(US)を通して、developerWorks コミュニティに参加できます。



著者について(原文のまま)
Robert Perron is a documentation architect with Lotus in Westford, Massachusetts. He has developed documentation for Lotus Notes and Domino since the early 1990's with a primary concentration on programmability. He developed the documentation for the LotusScript and Java Notes classes and coauthored the book 60 Minute Guide to LotusScript 3 - Programming for Notes 4. He has authored several LDD Today articles. He also authored "A Comprehensive Tour of Programming Enhancements in Notes/Domino 6" for The View.
 
上に戻る