Nachrichten verschicken mit SOAP - Die SOAP-Spezifikation

02.02.2007 von Dr. Klaus Manhart
SOAP ist ein wichtiges Protokoll für den Datenaustausch in einer dezentralen Umgebung wie dem Internet und bildet die Kommunikationskomponente von Web Services. Wer SOAP verstehen will, muss die Spezifikation und den Kommunikationsablauf kennen.

Mit SOAP (ursprünglich „Simple Object Access Protocol“) können Daten zwischen IT-Systemen auf einfache Weise ausgetauscht werden. Das typische Beispiel sind Informationen, die sich als XML-Dokument darstellen lassen wie HTML-Seiten, PDF-Dokumente, Verträge und Bestellformulare.

Der SOAP-Standard definiert allgemeine Regeln zum Transport solcher Nachrichten zwischen Applikationen und bietet insbesondere die Grundfunktionalität zur Kommunikation und dem Datenaustausch zwischen Web-Services.

Bei der Nachrichtenübermittlung stützt sich SOAP auf die Dienste anderer Standards, XML zur Repräsentation der Daten und Internet-Protokolle zur Übertragung der Nachrichten. Die gängigste Kombination ist SOAP über HTTP und TCP. Dadurch wird es Applikationen ermöglicht miteinander über HTTP zu kommunizieren und Komponenten auf anderen Systemen aufzurufen und auszuführen. Auf anderen Wegen und mit anderen Protokollen ist dies meist sehr schwierig, da Hindernisse wie eine Firewall den Zugriff auf Remote-Objekte verhindern.

Die eigentliche SOAP-Nachricht sieht ein Anwendungsentwickler, der eine Web Services Schnittstelle entwickelt, im Normalfall nicht. Trotz dieser Unsichtbarkeit ist es wichtig zu verstehen, wie eine SOAP-Nachricht aufgebaut ist. Denn eine genaue Kenntnis der SOAP-Spezifikation ist Voraussetzung, um das Potenzial einer SOAP-Kommunikation richtig einschätzen zu können.

SOAP-Spezifikationen - Dokumente

SOAP wurde durch die Standardisierung und die Bemühungen von Unternehmen wie Microsoft und IBM ein fester Bestandteil des Web-Services-Schichtenmodells, aber auch in konkurrierenden Ansätzen wie ebXML bleibt SOAP unbestritten.

2003 wurde die SOAP Version 1.2 als Empfehlungsvorschlag vom W3C anerkannt. Eine wichtige Änderung im Vergleich zur Version 1.1 war, dass SOAP seither kein Akronym mehr ist, da sämtliche Deutungen für SOAP, wie „Simple Object Access Protocol“ oder „Service Oriented Architecture Protocol“ den vollständigen Sinn von SOAP nicht treffen.

Das SOAP-Tutorial: Die Soap-Version 1.2 Part 0 gibt es auch in einer deutschen Übersetzung.

Die SOAP-Spezifikation der Version 1.2 ist in mehrere Dokumente aufgeteilt.

Kommunikations-Philosophie

Um SOAP zu verstehen, muss klar sein, dass es keinerlei Annahmen darüber macht, welcher Kommunikationskanal (Telefon, Brief, Funk) verwendet wird, welche Sprache genutzt wird oder wie die Daten verpackt werden (Gedicht, Bild, Prosa). Wichtig ist nur, dass sich Sender und Empfänger auf ein bestimmtes Verfahren einigen, und dieses einheitlich interpretieren.

Plakative Darstellung: Der Austausch einer SOAP-Nachricht im Überblick. (Quelle: Dostal et al: Serviceorientierte Architekturen mit Web Services, Elsevier/Spektrum)

Im ersten Schritt wählt der Sender einen Kommunikationskanal aus, über den der Empfänger erreichbar ist. Die Nachricht wird dann in einem Format verfasst, das der Empfänger versteht. Wird die Nachricht abgeschickt, muss sie so verpackt werden, dass sie auf dem gewählten Kanal transportiert werden kann und der Empfänger sie als Nachricht erkennt.

Auf Empfängerseite läuft der Prozess umgekehrt ab: Der Empfänger entpackt die Nachricht, list die Botschaft und interpretiert sie.

Die Nachricht kann über verschiedene Zwischenstationen zum Empfänger gelangen. Solche Zwischenstationen können zum Beispiel Relay-Stationen sein, die das Signal verstärken oder Gateways, die die Nachricht auf ein anderes Transportsystem setzen.

Ein solches Gebilde aus Kommunikationselementen und Verbindungen ist mathematisch betrachtet ein Graph, dessen Elemente als Knoten bezeichnet werden. Im SOAP-Konzept werden Sender, Empfänger und Zwischenstationen deshalb als Knoten („nodes“) bezeichnet, wobei jeder Knoten eindeutig über eine URI („Uniform Ressource Identifier“) identifizierbar sein muss.

Aufbau einer SOAP-Nachricht

Die genaue Spezifikation für den Aufbau einer SOAP-Nachricht ist in „SOAP Version 1.2 Part 1: Messaging Framework“ beschrieben. Prinzipiell ist eine SOAP-Nachricht ein XML-Dokument, das aus drei Blöcken besteht und nach dem Head-Body-Muster modelliert ist: Der SOAP-Envelope ist der Container, der ein optionales Header-Element und ein notwendiges Body-Element enthält.

SOAP-Nachrichtenstruktur: Eine SOAP-Nachricht besteht aus einem Envelope, einem Header und einem Body.

Der SOAP Envelope enthält die eigentliche Nachricht als „Briefumschlag“. Er bildet die Wurzel des XML-Dokumentes. In ihm sind die anderen beiden Teile enthalten. Das folgende Listing zeigt den grundsätzlichen Aufbau einer SOAP-Nachricht:

<env:Envelope
xmlns:env=’’HTTP://www.w3.org/2003/05/soap-envelope’’>
<!- SOAP Header -->
<!- SOAP Body -->
</env:Envelope

Mit der URI www.w3.org/2003/05/soap-envelope legen Sie fest, welche Version der SOAP-Spezifikation in der SOAP-Nachricht verwendet wird. Anhand des URI kann der Empfänger der Nachricht erkennen, dass es sich um eine SOAP-Nachricht der SOAP Version 1.2 handelt. Gleichzeitig definiert diese URI den Namespace im XML-Dokument, der an das Präfix „env“ gebunden ist.

Der SOAP Header

Der SOAP Header ist ein optionales Element. Dort werden die Metainformationen der Nachricht untergebracht. Dies können Informationen über das Routing der Nachricht, über eine eventuelle Verschlüsselung oder über die Zugehörigkeit zu einer Transaktion sein. Der Header kann genau einmal vorkommen und muss das erste Element des Envelopes sein.

Die Blöcke werden durch einen eindeutigen URI identifiziert und können so den Knoten zugeordnet werden. Durch diesen Mechanismus bleiben SOAP-Nachrichten flexibel und können durch die zusätzliche Spezifikation von solchen Blöcken erweitert werden, ohne Information über die eigentlichen kommunizierenden Partner vorauszusetzen.

Übertragen werden können beliebige Informationen, wobei in der Praxis bestimmte Bereiche dominieren. Ein typisches Anwendungsgebiet für das Übertragen im Header sind etwa Sicherheitsinformationen:

1 <?xml version="1.0" ?>
2 <env:Envelope xmlns:env="http://www.w3.org/2002/12/soap-envelope">
3 <env:Header>
4 <login:sicherheit xmlns:login=http://example.com
5 env:role=http://example.com/Login
6 env:mustUnderstand=“true“>
7 <login:benutzername>Peter Muster</login:benutzername>
8 <login:passwort>meinpasswort</login:passwort>
9 </login:sicherheit>
10 <audit:administration xmlns:audit=http://example.com/audit
11 env:role="http://www.w3.org/2002/12/soap-envelope/role/next">
12 ...
13 ...
14 </audit:administration>
15 </env:Header>
16 <env:Body >
17 ...
18 ...
19 </env:Body>
20 </env:Envelope>

Eine SOAP-Nachricht muss nicht immer direkt vom Sender zum Empfänger übertragen werden. Sie kann ihr Ziel auch über mehrere Zwischenstationen („Intermediares“) erreichen. Header-Elemente können direkt an solche Zwischenstationen adressiert sein. Jede der Stationen muss dabei die Header-Elemente verstehen und bearbeiten können.

Hat eine Zwischenstation ein Element bearbeitet, muss es aus der Nachricht entfernt oder zumindest abgeändert werden. Um genau zu bestimmen, wie ein Header-Element verarbeitet werden muss, können für jedes Element weitere Attribute definiert werden.

In dem Beispiel oben gibt es für die Elemente im Header (Zeile3) die Vorgabe, maximal drei Attribute besitzen zu dürfen: „mustUnderstand“, „role“ und „relay“. Das Attribut „role“ (Zeile 5) etwa spezifiziert den Empfänger bzw. die Zwischenstation, die das Header-Element verarbeiten darf. Diese können über eine gültige URI identifiziert werden.

Das mustUnderstand (Zeile 6) Attribut nimmt die Werte true oder false an und kann benutzt werden, um den Empfänger der SOAP-Nachricht mitzuteilen, dass das zugehörige Header-Element auf jeden Fall von ihm verstanden werden muss. Falls der Empfänger diese Nachricht nicht verarbeiten kann, muss er sie ablehnen.

Der SOAP Body

Das zweite Element einer SOAP-Nachricht ist der SOAP Body. Er ist zwingend erforderlich und wird mit dem Schlüsselwort „Body“ eingeleitet.

<env:Body>
<m:transaction xmlns:m=’’http://www.w3.org/2003/05/soap-envelope’’>
<m:msg>
NUTZDATEN - HIER STEHT DIE ZU TRANSPORTIERENDE INFORMATION
</m:msg>
</m:transaction>
</env Body>

Der Body enthält den Kern einer SOAP-Nachricht, die eigentlichen Nutzdaten („Payload“). Der Inhalt muss ein wohlgeformtes XML-Dokument darstellen und ist Teil eines Vertrages zwischen den Kommunikationspartnern. Je nachdem, welche Partner in welchem Kontext kommunizieren, ist die Struktur der Information im Vorhinein zu vereinbaren.

SOAP-Envelope: Header und Body im Detail.

Der Inhalt selbst ist anwendungsbezogen und kann hier nicht weiter erläutert werden. Die Daten können unter anderem für entfernte Methodenaufrufe, (Fehler-)Meldungen oder reine Daten wie zum Beispiel Abbildung einer Klassenstruktur stehen.

Als einfaches Beispiel betrachten wir den SOAP Call vom Client zum Server:

<env Envelope
xmlns:env=’’http://www.w3.org/2003/05/soap-envelope’’>
<env:Body>
<GetServerTime></GetServerTime>
</env:Body>
</env:Envelope>

Diese SOAP Nachricht will am Server die GetServerTime() Funktion aufrufen. Der Client schickt nun an den Server diese Nachricht und dieser gibt folgenden Response zurück - falls er eine solche Methode zur Verfügung stellt:

<env Envelope
xmlns:env=’’http://www.w3.org/2003/05/soap-envelope’’>
<env:Body>
<GetServerTimeResponse>
<Now>04/01/2007 12:00:00 AM</Now>
</GetServerTimeResponse>
</env:Body>
</env:Envelope>

Auf der Client-Seite bekommt man nun den Wert der Funktion zurückgesandt.

SOAP-Fehler

Bei der Kommunikation können an verschiedenen Stellen der Kommunikationskette Fehler auftreten. Teil 1 der SOAP Spezifikation ist diesem Thema gewidmet. Die Spezifikation schreibt vor, dass im Fall eines Fehlers ein SOAP Fault Block als einziges Element des SOAP Body übertragen werden darf.

Der Namespace des Fault Blocks muss dabei mit dem URI HTTP://www.w3.org/2002/12/soap-envelope definiert werden. Dabei müssen in dem Fault Block die Elemente der folgenden Tabelle enthalten sein, ein Teil davon ist fakultativ:

Die Elemente des SOAP Fault Blocks

Elementname

Status

Beschreibung

Code

Verpflichtend

Von der SOAP Spezifikation festgelegte Codierung der Fehlerquelle

Reason

Verpflichtend

Textuelle Beschreibung des aufgetretenen Fehlers

Node

Fakultativ

Gibt an, an welcher Stelle der SOAP Kommunikation der Fehler aufgetreten ist

Role

Fakultativ

Beschreibt die Rolle des Knotens, bei dem der Fehler aufgetreten ist

Detail

Fakultativ

Enthält weitere Infos zum aufgetretenen Fehler. Der Inhalt kann von den Anwendungen frei festgelegt werden

Als Beispiel sei hier nur das erste Element „Code“ beschrieben, die anderen können bei Bedarf im Teil 1 der Spezifikation nachgelesen werden.

„Code“ besteht aus zwei Elementen: dem verpflichtenden „Value“, das den Fehlercode der Fehlermeldung enthält und dem optionalen „Subcode“, das die genaue Spezifikation des Fehlercodes im Element „Value“ ermöglicht.

Bearbeitung einer SOAP-Nachricht

Bislang wurde geklärt, was mit einem SOAP-Aufruf übertragen werden kann. Die zweite Frage ist, wie die Nachricht zum Empfänger kommt.

Die Bearbeitung einer SOAP-Nachricht erfolgt durch eine „Schritt-für-Schritt“ Versendung entlang eines so genannten Nachrichtenpfades. Der erste Knoten des Nachrichtenpfades ist dabei der „initial SOAP sender“, also der Knoten, von dem die Nachricht ursprünglich gesendet wurde. Der letzte Knoten in der Kette heißt „ultimate SOAP receiver“.

Alle dazwischen liegenden Knoten übernehmen die Aufgabe eines SOAP-Vermittlers („intermediary“). Jedem Knoten kann dabei eine bestimmte Rolle zugeordnet werden, die eindeutig durch einen URI identifiziert werden kann. Zumindest die spezielle Rolle "HTTP://www.w3.org/2001/09/soap-envelope/actor/next" muss von jedem Vermittler-Knoten erfüllt werden. Sie drückt aus, dass der Knoten als Folgeknoten in dem Nachrichten-Pfad angesprochen werden kann. Zwischenknoten können zusätzlich noch beliebige weitere Rollen erfüllen.

Die Identifikation der Knoten und hier besonders die des Endknotens erfolgt über die Identifizierungsmechanismen der darunter liegenden Knoten. Im Falle von TCP bzw. HTTP entspricht dies der IP-Adresse oder der URL. Jeder Knoten, der eine Nachricht erhält, muss in gewisser Weise darauf reagieren. Das heißt, er muss entweder die Nachricht bearbeiten, beantworten oder einen SOAP-Fehler auslösen.

Transport-Protokolle - Beispiel HTTP

Zur Übertragung von SOAP-Nachrichten erlaubt die SOAP-Spezifikation die Verwendung beliebiger Transportprotokolle. Dazu gehören etwa HTTP, SMTP, FTP, JMS oder RMI. Diese Verfahren beschreiben alle, wie eine Nachricht jeweils auszutauschen ist.

Die Wahl des Transportprotokolls hängt von den jeweiligen Anforderungen ab. Wird ein Protokoll benötigt, das praktisch überall zur Verfügung steht, so ist HTTP eine gute Wahl. Wird allerdings Wert gelegt auf hohe Übertragungssicherheit, kommen andere Protokolle wie das Messaging-System WebSphereMQ in Frage.

Die Verwendung von HTTP als zugrunde liegendes Protokoll ist bisher am weitesten verbreitet. Bei der Verwendung von HTTP übernimmt man die Vorteile dieses Protokolls für die Verwendung mit Web-Services:

  1. HTTP ist überall verfügbar und ermöglicht auch Verbindungen über Firewalls.

  2. Die Einbindung von SOAP-Nachrichten in HTTP-Aufrufe gestaltet sich einfach.

  3. HTTP-Server sind weit entwickelt und erlauben großen Datenverkehr (Skalierbarkeit).

  4. Die Sicherheitskonzepte für HTTP können auf SOAP-Nachrichten angewendet werden.

SOAP-Nachricht mit HTTP Request

Die Übertragung von SOAP-Nachrichten über HTTP folgt dem Request-Response Muster. Dabei werden eine SOAP-Request-Nachricht im HTTP-Request und die SOAP-Response-Nachricht im HTTP-Response übermittelt. Intermediary-Funktionen werden von der Laufzeitumgebung am Empfängerknoten übernommen, da das SOAP-intermediary-node-Konzept nicht von HTTP übernommen werden kann.

Zur Übermittlung einfacher Kontext-Informationen an die Web-Services des Empfängers kann das SOAP-action-Feld im HTTP-Header verwendet werden. Die Beantwortung einer SOAP-Nachricht durch die SOAP-HTTP-Response erfolgt in Form der HTTP-Status-Codes. Ein 2xx Status-Code bedeutet beispielsweise die erfolgreiche Abarbeitung der SOAP-Nachricht. Tritt ein Fehler beider Bearbeitung der Nachricht auf, enthält der Response den HTTP-500-„Internal Server Error“-Code und eine SOAP-Nachricht mit den entsprechenden SOAP-Fehlermeldungen im Anhang.

Es können auch andere Bindings für SOAP verwendet werden. Die Security-Erweiterung SSL von HTTPs erlauben eine einfache Möglichkeit, SOAP-Nachrichten in ein sicheres Umfeld einzubetten. Eine weitere Option ist, SOAP-Nachrichten über das SMTP-Protokoll zu transportieren. Dies ermöglicht asynchronen Datenaustausch zwischen Web-Services. Asynchrone Kommunikation ist in vielen B2B-Szenarien die geeignete und explizit erwünschte Art des Nachrichtenaustausches.

Die Kommunikation über Java Messaging Service (JMS) erlaubt die Integration von Web-Services in Business-Anwendungen der J2EEPlattformen. Enterprise-Java-Beans(EJB)-Aufrufe aus Web-Services und umgekehrt werden dadurch ermöglicht.

Fazit

Mit der XML-Anwendung SOAP lassen sich prinzipiell beliebige XML-Dokumente übertragen. Sie ist ein plattform- und programmiersprachenunabhängiges Konzept zur Übermittlung von Daten in dezentralen Umgebungen, insbesondere dem Internet.

Die SOAP-Spezifikation legt fest, dass eine vollständige SOAP-Nachricht aus einem Envelope, einem Body und einem fakultativen Header-Element besteht. Da SOAP nur das Nachrichtenformat beschreibt, kann eine SOAP-Nachricht mit Hilfe eines beliebigen Transport-Protokolls übertragen werden. (hal)