レベル: 上級 Robert Perron, Documentation architect, IBM Corporation
2004年 09月 27日 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 の図
外部の世界に対してオペレーションを利用可能にするために、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 Services] プロパティボックスには、エージェントと同様に 3 つのタブがあります。[基本] タブを次の図に示します。
図 3. [Web Services] プロパティボックス
名前は必須です。別名とコメントは、入力してもしなくてもかまいません。コードの変更によって新規の WSDL が生成されるときに警告を受けるよう指定できます。
[PortType class] は、WSDL オペレーションに対応するプロシージャーを定義するクラスの名前です。これらのプロシージャーは、LotusScript ではパブリックの関数またはサブルーチン、Java ではパブリックのメソッドであることが必要です。プライベートの関数、サブルーチン、メソッドは、Web サービス・インターフェースを介しては公開されません。コーディングまたは WSDL のインポートによってクラスを作成するまでは、プロパティボックスの [PortType class] には入力できません。コードについては、後で詳しく説明します。
[セキュリティ] タブは、エージェントの [セキュリティ] タブとほとんど同じ内容です。セキュリティについては、後で詳しく説明します。
[詳細] タブには、Web サービスの定義と WSDL の生成に関する詳細情報が含まれています。この点についても、後で詳しく説明します。
プログラムペインもエージェントの場合と同様です。右側のドロップダウンボックスで、LotusScript または Java を選択できます。Java を選択したようすを下図に示します。左側には、[Objects] と [Reference] の各ペインがあります。
図 4. 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 がロードした後、次のように操作します。
- [WSDL Page] アイコンをクリックします。これは、右上の右矢印から 3 番目のアイコンです。左側の [Navigator] ペインに、[WSDL Main] リンクが表示されます。
- [WSDL Main] リンクをクリックします。右側のペインに [Open WSDL] ボックスが表示されます。
- /WSDL コマンドを付けて Web サービスの URL を入力し(例: http://rperron300pl.notesdev.ibm.com/Webservices2.nsf/GetSubject?
WSDL)、[Go] をクリックします。Web Services Explorer がこの時点で WSDL 文書を読み込むので、/OpenWebService
ではなく /WSDL が必要になります。
- 右側のペインに [WSDL Binding Details] ボックスが表示されます。これには、
Web サービスによって定義されたオペレーションへのリンクが含まれています。
- オペレーションの名前 (例: getNthSubject) をクリックします。[Invoke a WSDL Operation] ボックスが表示されます。
- オペレーションの名前 (例: getNthSubject) をクリックします。[Invoke a WSDL Operation] ボックスが表示されます。
レスポンスは、一番下のペイン (Status) に戻されます。サンプルの Web サービスを呼び出した後の Web Services Explorer を下図に示します。
図 5. 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] プロパティボックスの [詳細] タブ
このタブでは、ポートタイプ、サービス要素、およびサービスポートのそれぞれの名前を指定できます。たとえば、すべての名前を 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] プロパティボックスの [セキュリティ] タブ
最初の 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 NotesSession
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 サービスのコードをスクリプトライブラリに保存可能にするような計画もあります。
参考文献
著者について  | |  | 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. |
記事の評価
|