Web Services mit SOAP nutzen

15.06.2006 von Elmar Fuchs
Um die in Domino 7 entwickelten Web Services nutzen zu können, wird ein Client benötigt. MS SOAP eröffnet eine einfache Möglichkeit, einen solchen zu erstellen. Damit lässt sich die Funktionalität von Web Services auch relativ einfach testen. Hier spielt auch das Zusammenspiel mit LotusScript eine nicht unwichtige Rolle.

Web Services sind ein wichtiges Element von SOA, der Service-orientierten Architektur. Dabei agieren Anwendungen nicht als Insellösungen, sondern können als Dienst bzw. als Service von anderen Anwendungen in Anspruch genommenwerden.

Mit der Version 7 von Notes Domino ist es möglich, innerhalb einer Notes-Datenbank mit dem Domino Designer Web Services als gemeinsamen Code zu entwickeln und diese über den Domino-Server zur Verfügung zu stellen. Voraussetzung dafür ist, dass auf dem Domino-Server der HTTP-Task läuft. In einer losen Folge von Artikeln wollen wir uns mit den daraus entstehenden Anforderungen und resultierenden Möglichkeiten beschäftigen.

Im Artikel „Web Services in Domino“ in der letzten Ausgabe der Expert´s Inside Lotus Notes/ Domino standen die möglichen Einstellungen in den Eigenschaften eines Web Service und der daraus resultierende Aufbau der WSDL-Datei sowie die verschiedenen Programmier- und SOAP-Nachrichtenmodelle im Mittelpunkt. Der als Beispiel entwickelte Web Service lieferte einen Wert als Ergebnis und wurde mit Hilfe eines Agenten innerhalb von Notes Domino getestet. Der vorliegende Artikel zeigt, wie Sie für den Test des Web Service einen MS SOAP-Client entwickeln können. Dazu erstellen wir sowohl mit VBScript als auch mit LotusScript jeweils einen Testclient. Außerdem wollen wir unseren Beispielagent so erweitern, dass er als Ergebnis nicht nur einen einzelnen Wert, sondern mehrere zurückgibt.

Clientvarianten

Um einen Web Service zu nutzen, benötigen Sie einen Client. Dieser richtet eine Anfrage in Form einer SOAP-Datei (Simple Object Access Protocol) an den Web Service und wertet die von diesem gelieferte Antwort aus. Notes Domino selbst bietet in der aktuellen Version 7 keine Möglichkeit, einen solchen Client zu erstellen. Wollen Sie dies innerhalb des Domino Designer realisieren, müssen Sie den benötigten Programmcode als Agent oder Bestandteil einer Skriptbibliothek in Java oder LotusScript schreiben.

Außerhalb des Domino Designer existiert jedoch eine Vielzahl von Werkzeugen, die Sie bei der Web Service-Clientprogrammierung unterstützen. Exemplarisch seien an dieser Stelle IBM Rational Application Developer 6 (RAD 6), Eclipse unter Einbeziehung des Web Tools-Plug-Ins, Microsoft SOAP Toolkit und PocketSOAP genannt.

Die Mächtigkeit der genannten Werkzeuge ist recht unterschiedlich. Während es sich bei RAD 6 und Eclipse um komplette integrierte Entwicklungsumgebungen handelt, sind die beiden letztgenannten Werkzeuge Toolkits. MS SOAP stammt, wie es der Name sagt, von Microsoft. PocketSOAP ist ein Open-Source-SOAP-Client in Form einer COM-Komponente. Ursprünglich für Pocket-PC entwickelt, gibt es mittlerweile auch eine Version für Win32. Diese läuft unter den gängigen Windows-Versionen 95, 98, Me, NT4, 2000, XP und 2003.

Im Folgenden sehen wir uns MS SOAP etwas näher an. Informationen zu PocketSOAP finden Sie unter www.pocketsoap.com/pocketsoap.

MS SOAP-Toolkit

Das Microsoft SOAP-Toolkit umfasst Komponenten, die zum einen der Erstellung von Web Services und zum anderen der Erstellung von Clients zur Nutzung von Web Services dienen. Die letzte verfügbare Version des Toolkits ist 3.0. Die weitere Entwicklung wurde zugunsten des .Net Frameworks aufgegeben. Das SOAP-Toolkit besitzt damit den Status „deprecated“.

Obwohl das Toolkit damit scheinbar veraltet ist, ist es für unsere Zwecke interessant, da Microsoft in Windows XP Professional den SOAPClient des Toolkits integriert hat. Dieser ist über jede Programmiersprache ansprechbar, die das Microsoft Common Object Model (COM) unterstützt. Nutzt ein Client-PC als Betriebssystem Windows XP Professional, kann somit der vorhandene SOAP-Client für die Auswertung und Verarbeitung der von Web Services gelieferten Ergebnisse genutzt werden. Bei Verwendung von Windows 2000 als Betriebssystem ist eine separate Installation des MS SOAP-Toolkits auf jedem Computer notwendig, auf welchem der Client des Web Services laufen soll.

Ein Nachteil des MS SOAP-Clients ist, dass Sie bei der Wahl des Programmier- und Nachrichtenmodells eingeschränkt sind. Zur Auswahl stehen lediglich RPC/Encoded und RPC/Literal. Bei der Verwendung von RPC Wrapped oder RPC Doc/Literal erhalten Sie eine SOAP-Fehlermeldung in der Form

Soapmapper: Restoring data into <Methodenname>Return
failed

Versuchen Sie, das Programmiermodell Message zu nutzen, erfolgt eine Fehlermeldung des WSDLReaders:

WSDLReader: No valid schema specification was found.

Methoden und Eigenschaften

Für den SOAP-Client wird ein SOAP-Client- Objekt verwendet, das eine Methode zur Initialisierung des SOAP-Clients bietet. Daneben kann es über eine Reihe von Eigenschaften gesteuert werden. Tabelle 1 enthält einen Überblick über die vorhandenen Methoden und Eigenschaften.

Tabelle 1: Die Methoden und Eigenschaften des SOAP-Client-Objekts

Methoden und Eigenschaften

Beschreibung

MSSOAPInit

Mit dieser Methode wird das SOAP-Objekt unter Verwendung einer WSDL-Datei als Parameter in initialisiert.

ClientProperty

Über diese Eigenschaft werden Eigenschaften des Objekts, zum Beispiel der Parameter ServerHTTPRequest, gesteuert.

ConnectorProperty

Die Eigenschaft dient den Einstellungen des Transportprotokolls.

Detail

Diese Eigenschaft gibt den Wert des Elements <Detail> innerhalb der Fehlerbehandlung des SOAP-Objekts zurück.

HeaderHandler

Die Methode setzt den Handler des Headers für den nächsten Aufruf der Client-Instanz.

Faultactor

Die Eigenschaft gibt beim Auftreten eines Fehlers die den Fehler erzeugende URI zurück.

Faultcode

Die Eigenschaft gibt beim Auftreten eines Fehlers den Fehlercode zurück.

FaultString

Die Eigenschaft gibt beim Auftreten eines Fehlers den Wert des Elements <FaultString> innerhalb der Fehlerbehandlung des SOAP-Objekts zurück.

Einen Client mit VBScript erstellen

Um einen Client über die SOAP-API (Application Programming Interface) zu erzeugen, sind drei Schritte notwendig:

Die Erstellung des SOAP-Client-Objekts.

Die Erstellung des Objekts realisieren Sie mittels der Methode CreateObject():

Dim SOAPClient
Set SOAPClient = createObject("MSSOAP.SOAPClient")

Für die Initialisierung nutzen Sie die Methode MSSoapInit() des erzeugten SOAP-Client-Objekts:

SOAPClient.msSoapInit("<WSDL-Datei>")

Zuletzt rufen Sie eine Methode des Web Service auf:

wscript.echo SOAPClient.getPreis("<Paramater>")

Wir verwenden unseren einfachen Web Service zur Ermittlung eines Reisepreises für eine bestimmte Reisenummer. Listing 1 enthält den vollständigen Programmcode in VBScript unter Berücksichtigung einer einfachen Fehlerprüfung. Diese Thematik wird Gegenstand eines eigenen Artikels in einer der kommenden Ausgaben von Expert´s inside Lotus Notes/Domino sein.

Dim SOAPClient
Set SOAPClient = createobject("MSSOAP.SOAPClient")
On Error Resume Next
SOAPClient.mssoapinit("http://localhost/webservice2.nsf/webservicedemo1?wsdl")
If err Then
wscript.echo SOAPClient.faultString
WSCRIPT:ECHO SOAPClient.detail
End If
wscript.echo SOAPClient.getPreis("D-12")
If err Then
wscript.echo SOAPClient.faultString
WSCRIPT:ECHO SOAPClient.detail
End If

Im Beispiel wird der Rückgabewert des Web Service auf der Konsole ausgegeben. Das Ergebnis zeigt Bild 1. Voraussetzung für einen lokalen Test ist das Vorhandensein eines Systemdienstes, der eine über das Web gestellte Anfrage beantworten kann. Andernfalls erfolgt eine Fehlermeldung des WSDLReaders:

Bild 1: Der Rückgabewert des Web Service.

WSDLReader: XML Parser failed at linenumber 0,
lineposition 0, reason is: resource
not found

Als Notes-Anwender bietet sich natürlich die Verwendung des lokalen HTTP-Tasks an. Um ihn zu aktivieren, starten Sie einmalig die Web-Vorschau einer Datenbank im Notes-Client über den Menüpunkt Aktionen/Vorschau im Web- Browser/Vorgabe-Browser. Wollen Sie kontrollieren, ob der lokale HTTP-Task läuft, öffnen Sie den Windows-Taskmanager. Ist der Task gestartet, finden Sie im Register Prozesse den Prozess nhttp.exe.

Test mittels LotusScript

Um den SOAP-Client in einem LotusScript-Agent zu nutzen, müssen wir zwei verschiedene externe Objekte erzeugen: ein Windows Script Host (WSH)-Objekt und ein COM-Objekt.

Für den Test, welcher SOAP-Client vorhanden ist, werten wir einen Registry-Eintrag aus. Anhand des Schlüssels HKLM\Software\Microsoft\ WindowsNT\CurrentVersion\CurrentVersion bestimmen wir das vorhandene Betriebssystem. Ist Windows XP installiert, wird der integrierte SOAP-Client verwendet, bei Windows 2000 der des Toolkits. Letzterer muss dann separat installiert worden sein. Bei anderen Windows-Versionen wird die Abarbeitung abgebrochen. Für die Auswertung nutzen wir das Objekt WScript.Shell des WSH:

Dim wshShell As Variant
Set wshShell = CreateObject("WScript.Shell")
version =
wshShell.RegRead("HKLM\Software\Microsoft\Windows
NT\_
CurrentVersion\CurrentVersion")
If version = "5.1" Then 'XP vorhanden
objName = "MSSOAP.SoapClient"
Elseif version ="5.0" Then '2k vorhanden
objName ="MSSOAP.SoapClient30"
Else
Msgbox "Win XP oder Win2K werden benötigt", 16,
"Falsches BS"
Exit Function
End If

Ausführliche Informationen und weitere Beispiele zur Nutzung des WSH erhält der Artikel „LotusScript und der WSH“ in dieser Ausgabe von Expert´s Inside Lotus Notes/Domino.

Je nach ermittelter Betriebssystemvariante wird danach der vorhandene SOAP-Client als externes COM-Objekt erstellt:

Set SoapObj = createObject(objName)
Call SoapObj.msSoapInit(wsdl)

Programmcode des Agenten

Listing 2 enthält den Programmcode des Agenten, einschließlich der Funktion getMSSOAP() zur Erzeugung des SOAP-Clients.

Declarations
Dim soapObj As Variant
Initialize
Sub Initialize
Dim se As New NotesSession
Dim ws As New NotesUIWorkspace
Dim col As NotesDocumentCollection
Dim doc As NotesDocument
Dim rnr As String
Dim wsdlPfad As String
Dim erg As String
Dim preis As Double
Set col = ws.PickListCollection(PICKLIST_CUSTOM, _
False, "", "webservice.nsf", "AlleReisen", "Alle Reisen", _
"Ein Dokument wählen" )
Set doc = col.GetFirstDocument
If doc Is Nothing Then
Msgbox "Kein Dokument gewählt", 16, "Abbruch"
Exit Sub
Else
rnr = doc.Reisenummer(0)
wsdlPfad = "http://localhost/webservice2.nsf/webservicedemo1?wsdl"
erg = getMSSOAP(wsdlPfad)
If erg ="Error" Then
Msgbox "Fehler bei Erstellung MSSOAP Objekt", 16, "Fehler"
Exit Sub
Else
preis = soapObj.getPreis(rnr)
If preis<>0 Then
Msgbox "Der Preis für die Reise mit der Nummer " + Cstr(rnr) _
+ " beträgt: " + Format(preis,"Currency"),,"Reisepreis"
Else
Msgbox "Reise nicht gefunden", 16, "Fehler"
End If
End If
End If
End Sub
Function getMSSOAP(wsdl As String) As String
Dim objName As String
Dim version As String
Dim wshShell As Variant
Set wshShell = CreateObject("WScript.Shell")
version = wshShell.RegRead("HKLM\Software\Microsoft\Windows NT\_
CurrentVersion\CurrentVersion")
If version = "5.1" Then
objName = "MSSOAP.SoapClient"
Elseif version ="5.0" Then
objName ="MSSOAP.SoapClient30"
Else
Msgbox "Win XP oder Win2K werden benötigt", 16, "Falsches BS"
Exit Function
End If
Set SoapObj = CreateObject(objName)
Call SoapObj.mssoapinit(wsdl)
End Function

Für die lokale Anwendung des SOAP-Clients
über einen LotusScript-Agent muss natürlich
ebenso wie bei der Variante über VBScript die
Web-Vorschau gestartet werden.

Mehrere Rückgabewerte eines Web Service

In unserem bisherigen Beispiel gibt der Web Service lediglich einen Wert zurück. Wollen wir mehrere Werte als Ergebnis erhalten, beispielsweise alle Stationen einer Rundreise, reicht diese Variante nicht aus. Problematisch ist jedoch, dass LotusScript die Rückgabe eines Feldes als Ergebnis einer Funktion nicht unterstützt.

Abhilfe schafft hier die Verwendung einer Klasse. Funktionen können eine Klasse oder genauer ein Objekt einer Klasse als Rückgabewert liefern. Erstellen wir also eine Klasse, die wiederum ein Feld enthält,

Class FeldReiseziele
Public Reiseziele() As String
End Class

können wir die Rückgabe mehrerer Werte von einem LotusScript Web Service realisieren:

Function getReiseziele(Reisenummer As String) As
FeldReiseziele
...
getReiseziele.Reiseziele(i) = doc.Reiseziel(i)
...
End Function

Listing 3 zeigt das Beispiel eines LotusScript- Web Service, der nach Auswahl einer Reisenummer alle Reisestationen der Rundreise in einem Mitteilungsfenster ausgibt (Bild 2).

Bild 2: Die grafische Ausgabe eines Web Service-Agents.

Dim se As NotesSession
Dim db As NotesDatabase
Dim vw As NotesView
Class FeldReiseziele
Public Reiseziele() As String
End Class
Class ReisezielInfo
Sub new
Set se = New NotesSession
Set db = se.CurrentDatabase
Set vw = db.GetView("AlleReisen")
End Sub
Function getReiseziele(Reisenummer As String) As FeldReiseziele
Dim doc As NotesDocument
Dim i As Integer
Set getReiseziele = New FeldReiseziele
Set doc = vw.GetDocumentByKey(Reisenummer)
If doc Is Nothing Then
Redim getReiseziele.Reiseziele(0 To 0)
getReiseziele.Reiseziele(0) ="Reise mit dieser Nummer nicht vorhanden"
Else
Redim getReiseziele.Reiseziele(0 To Ubound(doc.Reiseziel))
For i = 0 To Ubound(doc.Reiseziel)
getReiseziele.Reiseziele(i) = doc.Reiseziel(i)
Next
End If
End Function
End Class

Test des Web Service

Der Test des Web Service erfolgt durch die Implementierung des Web Service als Agent mit zugehöriger Routine zum Aufruf (Listing 4) unter Angabe einer festen Reisenummer.

Sub Initialize
Dim frz As New FeldReiseziele
Dim rzi As New ReiseZielInfo
Dim ausgabe As String
ausgabe = ""
Set frz = rzi.getReiseziele("R-112")
Forall p In frz.Reiseziele
ausgabe = ausgabe + p + Chr(13)
End Forall
Msgbox ausgabe, 32, "WebService mit Agent testen"
End Sub

Die im Artikel beschriebene Beispieldatenbank steht auf der Website des Autors zum kostenlosen Download zur Verfügung.

Fehlerbehandlung

In einem Artikel in der folgenden Ausgabe von Expert’s inside Lotus Notes/Domino betrachten wir die Möglichkeiten der Fehlerbehandlung eines mit LotusScript programmierten Web Service. Der Artikel wird sich also wieder mit der Serverseite beschäftigen. Die Fehlerbehandlung ist eine der wesentlichen Herausforderungen, um ein zuverlässiges Verhalten von Web Services zu erreichen.