Bei dieser SOAP handelt es sich nicht etwa – wie der Name vermuten lässt – um ein Pflegeprodukt, sondern um den Namen eines Netzwerkprotokolls.
SOAP baut auf dem XML-Format auf und kommt hauptsächlich in Verbindung mit HTTP zur Kommunikation mit Webservices zum Einsatz.
Ursprünglich war SOAP die Abkürzung für Simple Object Access Protocol. Seit der aktuellen Version 1.2 hat man sich aber dazu entschlossen, SOAP als eigenständigen Namen zu verwenden. Unter anderem wohl auch aus dem Grund, dass das Protokoll nicht so einfach zu verwenden ist, wie gedacht.
Funktionsweise
Bei SOAP werden Nachrichten zwischen Sender und Empfänger ausgetauscht.
Diese Nachrichten haben die folgende Struktur:
<Envelope>
<Header>
...
</Header>
<Body>
...
</Body>
</Envelope>
Die Nachricht ist durch einen Umschlag (engl. Envelope) eingefasst und unterteilt sich in einen Körper (engl. Body) und einen optionalen Kopf (engl. Header). Im Körper werden die eigentlichen Nutzdaten übertragen. Im Kopf können weitere Informationen, beispielsweise zur Authentifizierung mitgeführt werden.
Beispiel
Unter der Adresse "http://www.thomas-bayer.com/axis2/services/BLZService" ist ein öffentlicher und freier Webservice zur Auflösung von Bankleitzahlen verfügbar.
Eine Anfragenachricht an diesen Dienst könnte wie folgend aussehen:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://thomas-bayer.com/blz/">
<s:Body>
<getBank>
<blz>10070000</blz>
</getBank>
</s:Body>
</s:Envelope>
Dabei wird die Methode getBank
aufgerufen und im Argumentwert blz
eine nachzuschlagende Bankleitzahl übertragen.
Die dazugehörige Antwortnachricht sieht dann etwa so aus:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<getBankResponse xmlns="http://thomas-bayer.com/blz/">
<details>
<bezeichnung>Deutsche Bank Fil Berlin</bezeichnung>
<bic>DEUTDEBBXXX</bic>
<ort>Berlin</ort>
<plz>10883</plz>
</details>
</getBankResponse>
</s:Body>
</s:Envelope>
Im Element getBankResponse
wird das Resultat des Methodenaufrufs übertragen. Das untergeordnete Element details
enthält unter anderem die Werte für die Bezeichnung und den Ort der zugehörigen Bankfiliale.
Implementierung
Da die Zahl der Webservices die diesen Standard voraussetzen stetig zunimmt, haben wir bereits mehrere Anfragen von Ihnen zu diesem Thema erhalten.
An dieser Stelle möchte ich Ihnen aufzeigen, wie eine Implementierung eines SOAP-Clients, zur Kommunikation mit einem SOAP-basierten Webservice, in CONZEPT 16 aussehen könnte.
Das am Ende des Artikels als Download angehängte Modul SysSOAP stellt ein SOAP-Objekt zur Verfügung, mit dem über Funktionsaufrufe Nachrichten zusammengesetzt, gesendet, empfangen und zerlegt werden können.
Beispiel
try
{
// Initialisierung: SOAP-Client-Instanz anlegen
tSOAP # SysSOAP:Init(
// Serveradresse
'http://www.thomas-bayer.com/axis2/services/BLZService',
// Namensraum
'http://thomas-bayer.com/blz/'
);
// Anfragekörper ermitteln
tSOAPBody # tSOAP->SysSOAP:RqsBody();
// Wert hinzufügen
tSOAPBody->SysSOAP:ValueAddInt('blz', 10070000);
// Anfrage versenden und Antwort empfangen
tSOAP->SysSOAP:Request('getBank', '""');
// Antwortkörper ermitteln
tSOAPBody # tSOAP->SysSOAP:RspBody();
// Element ermitteln
tSOAPElement # tSOAPBody->SysSOAP:ElementGet('details');
if (tSOAPElement > 0)
{
// Werte ermitteln
tSOAPElement->SysSOAP:ValueGetString('bezeichnung', var tBez);
tSOAPElement->SysSOAP:ValueGetString('bic', var tBIC);
tSOAPElement->SysSOAP:ValueGetString('ort', var tOrt);
tSOAPElement->SysSOAP:ValueGetString('plz', var tPLZ);
}
}
// Fehler ermitteln
tErr # ErrGet();
// Kein Fehler aufgetreten
if (tErr = _ErrOK)
{
// Werte ausgeben
WinDialogBox(0, 'getBank()',
'Bezeichnung: ' + tBez + sCRLF +
'BIC: ' + tBIC + sCRLF +
'Ort: ' + tOrt + sCRLF +
'PLZ: ' + tPLZ,
_WinIcoInformation, _WinDialogOK, 1
);
}
// Fehler aufgetreten
else
{
// SOAP-Fehler
if (tErr = _Err.SOAPFault)
{
// SOAP-Fehler ausgeben
WinDialogBox(0, 'getBank()',
'SOAP-Fehler: ' + tSOAP->SysSOAP:RspFaultCode() + sCRLF +
tSOAP->SysSOAP:RspFaultReason(),
_WinIcoError, _WinDialogOK, 1
);
}
// Allgemeiner Fehler
else
{
// Fehler ausgeben
WinDialogBox(0, '', 'Fehler: ' + CnvAI(tErr),
_WinIcoError, _WinDialogOK, 1
);
}
}
// Terminierung: SOAP-Client-Instanz freigeben
if (tSOAP > 0)
tSOAP->SysSOAP:Term();
Das Modul setzt die Version 5.7.02 von CONZEPT 16 voraus, die eine Fehlerkorrektur beim Schreiben von XML-Daten enthält.
Fazit
Mit den Bordmitteln von CONZEPT 16 lassen sich selbst vielschichtige Schnittstellen, wie das SOAP-Protokoll realisieren. Eine eigene Implementierung bietet dabei immer den Vorteil, jederzeit erweitert, korrigiert und an die eigenen Anforderungen angepasst werden zu können.
6 Antworten
Ja, die gibt es =). Die Daten werden im UTF-8-Zeichensatz geladen. Mit der Funktion StrCnv(…, _StrFromUTF8) können die Werte in den CONZEPT 16-Zeichensatz gewandelt werden.
@Florian: ok, das klappt nun 🙂
Aber gibt es einfache Möglichkeit auch gelesene Umlaute in C16 zu konvertieren? Z.B. bei der BLZ 70090100
Nein, die fehlt nicht. Die Zeile in der diese Prozedur aufgerufen wird, ist noch vom Debugging übrig geblieben. Ich habe sie jetzt entfernt. Danke für den Hinweis.
Kann es sein, dass in dem ZIP die Prozedur "SysMem" fehlt?
Danke Robs!
Ja, die einfache Verwendung war eines der Ziele das ich erreichen wollte. =)
Sieht sehr gut aus! Einfacher als mit der Implementierung lässt sich ein WebService bestimmt nicht abfragen. 🙂