soap Tutorial
Erste Schritte mit Seife
Suche…
Bemerkungen
In diesem Abschnitt erhalten Sie einen Überblick darüber, was Seife ist und warum ein Entwickler sie verwenden möchte.
Es sollte auch alle großen Themen in Seife erwähnen und auf die verwandten Themen verweisen. Da die Dokumentation für Seife neu ist, müssen Sie möglicherweise erste Versionen dieser verwandten Themen erstellen.
Versionen
Ausführung | Veröffentlichungsdatum |
---|---|
1.1 | 2000-05-08 |
1.2 | 2003-06-24 |
Allgemeine Information
SOAP ist eine Abkürzung für Simple Object Access Protocol (Simple Object Access Protocol) , das ein Protokoll definiert, mit dem Daten über einen Remote Procedure Call (RPC) mit anderen SOAP-Diensten oder -Clients ausgetauscht werden. Es ist in zwei Versionen erhältlich:
SOAP 1.2 ersetzt SOAP 1.1. Es wird daher empfohlen, SOAP 1.2 nach Möglichkeit zu verwenden.
Es wird oft auf HTTP / S aufgebaut und selten auf SMTP oder FTP, obwohl es es entsprechend dem Protokoll unterstützen würde. Obwohl HTTP häufig als zugrunde liegendes Transportprotokoll verwendet wird, verwendet SOAP nur eine begrenzte Teilmenge davon. Für das Senden von Anforderungen ist der POST
Vorgang von HTTP fast vollständig erforderlich. GET
Aufrufe sind theoretisch seit 1.2 möglich, obwohl das Dokument als URI-Parameter übergeben werden muss und daher eine Grenze von etwa 3000 Zeichen überschreiten kann, die von den meisten Frameworks abgelehnt wird. Sicherheitsbezogene Einstellungen werden normalerweise auch in einem speziellen SOAP-Header definiert.
Obwohl SOAP und REST als Web-Services bezeichnet werden, unterscheiden sie sich naturgemäß sehr. Einige Frameworks unterscheiden zwischen WS (für SOAP-basierte Dienste) und RS (für REST-basierte Dienste).
Die folgende Tabelle gibt einen kurzen Überblick über die Unterschiede zwischen den beiden Web-Service-Typen.
Aspekt | SEIFE | SICH AUSRUHEN |
---|---|---|
Standard | SOAP , WSDL | Kein Standard, nur ein architektonischer Stil |
Adressierung von Ressourcen | Indirekt über SOAP-Operationen | über eindeutige Ressourcenkennungen (URIs) |
Fehlerbehandlung | SOAP-Fehlermeldung | HTTP-Fehlerantwortcodes und optionaler Antworttext |
Daten Präsentation | XML | alle verfügbaren Kodierungen in HTTP |
HTTP-Verwendung | Als Transportprotokoll | Aktionen für Ressourcen (CRUD), die HTTP-Methoden zugeordnet sind (GET, POST, PUT, DELETE, ...) |
Transaktionsunterstützung | über den SOAP-Header | durch Modellieren einer Transaktion als Ressource |
Zustand | Stateful (SOAP-Aktion ist Teil der Anwendung) | Zustandslos (in sich geschlossene Anfragen) |
Service Discovery | UDDI / WSDL | Eigentlich nicht; Start-URI der API sollte jedoch eine Liste von Unter-APIs zurückgeben |
Methode | Im SOAP-Körper | HTTP-Methode |
Methodenargumente | Definiert durch XML-Schema in der WSDL | Entweder über HTTP-Header oder Path / Query- oder Matrix-Parameter innerhalb der URI |
Zustandsübergang | Schwer zu bestimmen, da nicht direkt auf Daten basiert | Nächster URI-Aufruf |
Caching-Unterstützung | Caching oft nicht erwünscht, | Einfach wie von HTTP definiert |
SEIFE
Eine SOAP-Anforderung besteht aus einem SOAP-Envelop, der ein body-Element und ein optionales Header-Element enthalten muss. Das Header-Element wird verwendet, um bestimmte Konfigurationen an den Dienst zu übergeben, z. B. WS-Security kann definieren, dass die Nachricht verschlüsselt ist, oder WS-Coordination / WS-Transaction kann definieren, dass die Nachricht innerhalb einer Transaktion ausgeführt werden muss.
Eine einfache SOAP 1.2-Anforderung über HTTP, die zwei Werte hinzufügt, kann folgendermaßen aussehen:
POST /calculator HTTP/1.1
Host: http://example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 224
<?xml version="1.0"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Body>
<m:AddValues xmlns:m="http://example.org/calculator">
<m:FirstValue>1</m:FirstValue>
<m:SecondValue>2</m:SecondValue>
</m:AddValues>
</env:Body>
</env:Envelope>
Eine Antwort auf die obige Beispielanfrage kann so aussehen
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 329
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/calculator">
<m:AddValuesResponse>
<m:Result>3</m:Result>
</m:AddValuesResponse>
</soap:Body>
</soap:Envelope>
Im obigen Beispiel wurde eine Anforderung definiert, die die AddValues
Methode mit den zwei Argumenten FirstValue
auf 1
und SecondValue
auf 2
SecondValue
. Die Anforderung führte zu einer Ausführung dieser Methode auf dem Remote-SOAP-Server, der als Ergebnis einen Wert von 3
berechnet hat, der in einem separaten Antwortelement gekapselt wird. Dies ist in der Regel der aufgerufene Methodenname plus einer nachgestellten Response
Durch Überprüfen der Antwort kann festgestellt werden, dass dies die Antwort eines vorherigen AddValue
Methode ist.
Unterschiede zwischen SOAP 1.1 und 1.2
SOAP 1.2 erlaubt andere Transportprotokolle als HTTP, sofern das Bindungsframework vom Protokoll unterstützt wird.
SOAP 1.1 basiert auf XML 1.0, während 1.2 auf XML Infoset basiert, mit dem die SOAP-Nachrichten mit anderen Serialisierern als mit dem von SOAP 1.1 verwendeten Standard-XML 1.0-Serialisierer serialisiert werden können. Dies ermöglicht beispielsweise das Serialisieren von Nachrichten als binäre Nachrichten und somit einen gewissen Aufwand für die XML-Natur der Nachricht. Darüber hinaus kann der Serialisierungsmechanismus des zugrunde liegenden Protokolls über die Datenbindung bestimmt werden.
Der Aspekt der Interoperabilität wurde auch mit SOAP 1.2 gefördert, indem ein spezifischeres Verarbeitungsmodell als sein Vorgänger definiert wurde, wodurch viele Interpretationsmöglichkeiten beseitigt wurden. SOAP with Attachment API (SAAJ), das den Betrieb von SOAP 1.1- und 1.2-Nachrichten ermöglicht, half vielen Framework-Implementatoren, Nachrichten zu verarbeiten und zu erstellen.
Web-Service-Interoperabilität
Web Service Interoperability (auch als WS-I bezeichnet) ist eine Interoperabilitätsrichtlinie, die von einigen bekannten Unternehmen wie IBM, Microsoft, Oracle und HP geregelt wird, um nur einige zu nennen. In diesen Richtlinien wird unter anderem empfohlen, nur ein einziges Stammelement innerhalb des SOAP-Rumpfs zu verwenden, auch wenn der SOAP die Verwendung mehrerer Elemente im Rumpf zulässt.
WS-I besteht aus
- WS-I-Basisprofil aka WSI-BP
- WS-I Grundlegendes Sicherheitsprofil
- Einfaches Seifenbindungsprofil
WSI-BP ist in 4 verschiedenen Versionen v1.0 (2004) , v1.1 (2006) , v1.2 (2010) , v2.0 (2010) verfügbar und definiert Interoperabilitätsrichtlinien für Kernwebdienstspezifikationen wie SOAP, WSDL und UDDI. Durch die Verwendung von WSDL (Web Services Description Language) können SOAP-Dienste ihre unterstützten Operationen und Methoden innerhalb eines zusammenhängenden Satzes für andere Endpunkte beschreiben. WSI-BP verwendet WSDL, um ein engeres Set zu definieren, als das vollständige WSDL- oder SOAP-Schema definieren würde. Dadurch wird ein Teil der Mehrdeutigkeit innerhalb der Spezifikation selbst beseitigt und somit die Interoperabilität zwischen Endpunkten verbessert.
WSDL
Um die verfügbaren SOAP-Operationen, ihre Parameter sowie die jeweiligen Endpunkte zum Aufruf an Clients anzukündigen, wird ein weiteres XML-basiertes Dokument verwendet, das als Web Services Description Language
oder kurz WSDL bezeichnet wird.
WSDL beschreibt den Serviceendpunkt, das Binden von SOAP-Nachrichten an Operationen, die Schnittstelle der Operationen sowie deren Typen an Clients. WSDL ist wie SOAP in 2 Versionen verfügbar, die sich in ihrer Syntax leicht unterscheiden, jedoch dem Client fast dieselbe Semantik ausdrücken.
WSDL 1.1
Eine WSDL 1.1-Beschreibung enthält einen service
, eine binding
, einen portType
und einen message
. Es kann weiter Schemas innerhalb der WSDL-Datei importieren oder definieren, wie aus einer WSDL-Beispieldatei ersichtlich ist, die dem oben gezeigten Taschenrechner-Beispiel entspricht:
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:calc="http://example.org/calculator"
xmlns:tns="http://example.org/calculatorService"
targetNamespace="http://example.org/calculatorService">
<!--
Abstract type definitions
-->
<wsdl:types>
<!--
<xs:schema>
<xs:import namespace="http://example.org/calculator" schemaLocation="calc/calculator.xsd" />
</xs:schema>
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://example.org/calculator"
targetNamespace="http://example.org/calculator"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<xs:element name="AddValuesRequest" type="tns:AddValuesType" />
<xs:element name="AddValuesResponse" type="tns:AddValuesResponseType" />
<xs:complexType name="AddValuesType">
<xs:sequence>
<xs:element name="FirstValue" type="xs:int" minOccurs="1" maxOccurs="1" />
<xs:element name="SecondValue" type="xs:int" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddValuesResponseType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Result" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:attribute name="Timestamp" type="xs:dateTime" />
<xs:element name="CalculationFailure">
<xs:complexType>
<xs:sequence>
<xs:element name="ErrorCode" type="xs:int" />
<xs:element name="Reason" type="xs:string" />
</xs:sequence>
<xs:attribute ref="tns:Timestamp" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!--
Abstract message definitions
-->
<wsdl:message name="AddValuesRequest">
<wsdl:part name="in" element="calc:AddValuesRequest" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="out" element="calc:AddValuesResponse" />
</wsdl:message>
<wsdl:message name="CalculationFault">
<wsdl:part name="fault" element="calc:CalculationFailure" />
</wsdl:message>
<!--
Abstract portType / interface definition
-->
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation name="AddValues">
<wsdl:documentation>Adds up passed values and returns the result</wsdl:documentation>
<wsdl:input message="tns:AddValuesRequest" />
<wsdl:output message="tns:AddValuesResponse" />
<wsdl:fault name="CalculationFault" message="tns:CalculationFault" />
</wsdl:operation>
</wsdl:portType>
<!--
Concrete binding definition
-->
<wsdl:binding name="CalculatorBinding" type="tns:CalculatorEndpoint">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="AddValues">
<soap:operation soapAction="http://example.org/calculator/AddValuesMessage" />
<wsdl:input>
<soap:body parts="in" use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body parts="out" use="literal" />
</wsdl:output>
<wsdl:fault name="CalculationFault">
<soap:fault name="CalculationFault" use="literal" />
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<!--
Concrete service definition
-->
<wsdl:service name="CalculatorService">
<wsdl:port name="CalculatorServicePort" binding="tns:CalculatorBinding">
<soap:address location="http://localhost:8080/services/calculator" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Ein service
definiert die konkreten Endpunkte, die der Service auf eingehende Anforderungen überwacht. Der binding
bindet eine Operation an einen konkreten Stil und definiert, welche Nachrichtenformate der Server erwartet oder was der Client erwarten kann.
Der abstrakte Abschnitt besteht aus einem portType
Block, der die vom Dienst angebotenen portType
definiert und welche Nachrichten ausgetauscht werden. Die Nachrichten werden in ihrem On-Block angegeben und mit den Schematypen verknüpft, für die die Argumente und Rückgabewerte Instanzen sind. Nachrichten können Parameter deklarieren oder Werte als inout
, out
oder in
out
inout
. Während die ersten beiden recht einfach zu erfassen sind, ahmen die letzteren das Verhalten von Argumenten nach, die als Referenz übergeben werden. Da Pass-by-Ref in einigen Sprachen nicht unterstützt wird, wird dieser Effekt häufig über bestimmte Handler simuliert.
WSDL 2.0
Derselbe Rechner kann in WSDL 2.0 folgendermaßen beschrieben werden:
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:description xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://www.w3.org/ns/wsdl"
xmlns:soap="http://www.w3.org/ns/wsdl/soap"
xmlns:calc="http://example.org/calculator"
xmlns:tns="http://example.org/calculatorService"
targetNamespace="http://example.org/calculatorService">
<!--
Abstract type definitions
-->
<wsdl:types>
<!--
<xs:schema>
<xs:import namespace="http://example.org/calculator" schemaLocation="calc/calculator.xsd" />
</xs:schema>
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://example.org/calculator"
targetNamespace="http://example.org/calculator"
elementFormDefault="qualified"
attributeFormDefault="qualified">
<xs:element name="AddValuesRequest" type="tns:AddValuesType" />
<xs:element name="AddValuesResponse" type="tns:AddValuesResponseType" />
<xs:complexType name="AddValuesType">
<xs:sequence>
<xs:element name="FirstValue" type="xs:int" minOccurs="1" maxOccurs="1" />
<xs:element name="SecondValue" type="xs:int" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddValuesResponseType">
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="Result" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:attribute name="Timestamp" type="xs:dateTime" />
<xs:element name="CalculationFault">
<xs:complexType>
<xs:sequence>
<xs:element name="ErrorCode" type="xs:int" />
<xs:element name="Reason" type="xs:string" />
</xs:sequence>
<xs:attribute ref="tns:Timestamp" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<!--
Abstract interface
-->
<wsdl:interface name="CalculatorInterface">
<wsdl:fault name="fault" element="calc:CalculationFault" />
<wsdl:operation name="AddValues" pattern="http://www.w3.org/ns/wsdl/in-out" style="http://www.w3.org/ns/wsdl/style/iri" wsdl:safe="true">
<wsdl:documentation>Adds up passed values and returns the result</wsdl:documentation>
<wsdl:input messageLabel="in" element="calc:AddValuesRequest" />
<wsdl:output messageLabel="out" element="calc:AddValuesResponse" />
<wsdl:outfault messageLabel="fault" ref="tns:fault" />
</wsdl:operation>
</wsdl:interface>
<!--
Concrete binding definition
-->
<wsdl:binding name="CalculatorBinding" interface="tns:CalculatorInterface" type="http://www.w3.org/ns/wsdl/soap" soap:protocol="http://www.w3.org/2003/05/soap/bindings/HTTP/">
<wsdl:operation ref="tns:AddValues" soap:mep="http://www.w3.org/2003/05/soap/mep/soap-response" />
<wsdl:fault ref="tns:fault" soap:code="soap:Sender" />
</wsdl:binding>
<!--
Concrete service definition
-->
<wsdl:service name="CalculatorService" interface="tns:CalculatorInterface">
<wsdl:endpoint name="CalculatorEndpoint" binding="tns:CalculatorBinding" address="http://localhost:8080/services/calculator" />
</wsdl:service>
</wsdl:description>
Unterschiede zwischen WSDL 1.1 und 2.0
Eine grafische Übersicht über die Unterschiede zwischen beiden Versionen ist in der folgenden Abbildung dargestellt.
( Quelle )
Wie aus dem Bild ersichtlich, wurde der message
entfernt, der jetzt im interface
ist. Außerdem wurden einige Elemente umbenannt, andere haben eine andere Syntax, aber im Allgemeinen machen beide WSDL-Versionen im Wesentlichen dasselbe wie Version 2.0, was im Vergleich zu 1.1 etwas weniger Schreibaufwand erfordert.
Neben der geringeren Größe bei der Definition von SOAP-basierten Diensten über WSDL 2.0 bietet die neuere Version auch Funktionen zum Definieren von REST-Diensten. WSDL 2.0 oder sogar WADL werden für RESTful-Dienste NICHT empfohlen, da sie der eigentlichen Idee widersprechen.
Welchen Stil bevorzugen?
Der Abschnitt WSDL-Bindung beschreibt, wie der Dienst an das SOAP-Nachrichtenprotokoll gebunden ist. Im obigen Beispiel wurde document
als Bindungsstil verwendet, der es erlaubt, den SOAP-Body wie gewünscht zu strukturieren, solange die resultierende Ausgabe eine gültige XML-Instanz ist. Dies ist der Standardbindungsstil, der häufig als Message-Oriented style
.
Im Gegensatz zum document
müssen RPC
Anforderungskörper sowohl den Operationsnamen als auch die Menge der Methodenparameter enthalten. Die Struktur der XML-Instanz ist daher vordefiniert und kann nicht geändert werden.
Neben dem Bindungsstil definiert der Bindungsabschnitt auch ein Übersetzungsmodell für Bindungen an SOAP-Nachrichten im Namen des literal
oder encoded
. Der Unterschied zwischen den beiden ist, dass literal
Modell hat zu einem benutzerdefinierten XSD Struktur anzupassen, die verwendet werden können , um die Anforderungen und Antworten zu bestätigen, während das encoded
Modell XSD - Datentypen wie verwenden hat xs:integer
oder xs:string
aber im Austausch muss sich daher kein benutzerdefiniertes Schema ergeben. Dies macht es jedoch schwieriger, den Nachrichtentext zu überprüfen oder die Nachricht über XSLT in ein anderes Format umzuwandeln.
Die Kombination des Bindungsstils mit dem Use-Modell ermöglicht tatsächlich 4 verschiedene Nachrichtenergebnisse. Ein fünfter Eintrag wird der Liste hinzugefügt, der häufig verwendet wird (obwohl er nicht wirklich zum Standard gehört).
- RPC / codiert
- RPC / wörtliche
- Dokument / verschlüsselt
- Dokument / Literal
- Dokument / Literal (verpackt)
Im Dokument- / Literalstil der Nachrichtenübertragung gibt es ein Muster, das als umschlossenes Dokument / Literal bekannt ist. Dies ist nur ein Muster und ist nicht Teil der WSDL-Spezifikation. Dieses Muster wird in JSR 224 (JAX-WS: Java-API für XML-basierte Webdienste) erwähnt. ( Quelle )
Der folgende Abschnitt enthält einen Überblick über die Unterschiede in Bezug auf die WSDL- oder Schemadeklaration und ihre Auswirkungen auf das resultierende SOAP-Nachrichtenformat beim Ändern des Bindungsstils oder der Verwendung von Modelldefinitionen.
RPC / codiert
WSDL:
...
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" type="xsd:int" />
<wsdl:part name="SecondValue" type="xsd:int" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" type="xsd:int" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'RPC' and use to 'encoded' -->
...
SOAP-Anfrage
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue xsi:type="xsd:int">1</FirstValue>
<SecondValue xsi:type="xsd:int">2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
SOAP-Antwort
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result xsi:type="xsd:int">3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Pros
- unkomplizierte WSDL
- Name des Vorgangs und Elemente, die in Anforderung und Antwort verfügbar sind
Cons
- Explizite Deklaration von XSI-Typen
- Schwer zu bestätigen
- Nicht WS-I-kompatibel
RPC / wörtliche
WSDL:
...
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" type="xsd:int" />
<wsdl:part name="SecondValue" type="xsd:int" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" type="xsd:int" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'RPC' and use to 'literal' -->
...
SOAP-Anfrage
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
SOAP-Antwort
<soap:envelope>
<soap:body>
<AddValuesResult>
<Result>3</Result>
</AddValuesResult>
</soap:body>
</soap:envelope>
Pros
- unkomplizierte WSDL
- Name des Vorgangs und Elemente, die in Anforderung und Antwort verfügbar sind
- Keine XSI-Typspezifikation erforderlich
- WS-I-konform
Cons
- Schwer zu bestätigen
Dokument / verschlüsselt
Sinn macht deshalb keinen Sinn.
Dokument / Literal
WSDL:
...
<types>
<schema>
<element name="FirstValueElement" type="xsd:int" />
<element name="SecondValueElement" type="xsd:int" />
<element name="ResultValueElement" type="xsd:int" />
</schema>
</types>
<wsdl:message name="AddValues">
<wsdl:part name="FirstValue" element="FirstValueElement" />
<wsdl:part name="SecondValue" element="SecondValueElement" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="Result" element="ResultValueElement" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'Document' and use to 'literal' -->
...
SOAP-Anfrage
<soap:envelope>
<soap:body>
<FirstValueElement>1</FirstValueElement>
<SecondValueElement>2</SecondValueElement>
</soap:body>
</soap:envelope>
SOAP-Antwort
<soap:envelope>
<soap:body>
<ResultElement>3</ResultElement>
</soap:body>
</soap:envelope>
Pros
- Keine XSI-Typcodierung
- Kann Körper validieren
- WS-I entspricht den Einschränkungen
Cons
- WSDL ist aufgrund der zusätzlichen XSD-Definition komplizierter
- Der Operationsname geht verloren
- WS-I lässt nur ein Kind im SOAP-Body zu
Dokument / Literal (verpackt)
WSDL:
...
<types>
<schema>
<element name="AddValues">
<complexType>
<sequence>
<element name="FirstValue" type="xsd:int" />
<element name="SecondValue" type="xsd:int" />
</sequence>
</complexType>
</element>
<element name="AddValuesResponse">
<complexType>
<sequence>
<element name="ResultValue" type="xsd:int" />
</sequence>
</complexType>
</element>
</schema>
</types>
<wsdl:message name="AddValues">
<wsdl:part name="in" element="AddValues" />
</wsdl:message>
<wsdl:message name="AddValuesResponse">
<wsdl:part name="out" element="AddValuesResponse" />
</wsdl:message>
<wsdl:portType name="CalculatorEndpoint">
<wsdl:operation="AddValues">
<wsdl:input message="AddValues" />
<wsdl:output message="AddValuesResponse" />
</wsdl:operation>
</wsdl:portType>
<!-- binding style set to 'Document' and use to 'literal' -->
...
SOAP-Anfrage
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
SOAP-Antwort
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result>3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Pros
- Keine XSI-Typcodierung
- Kann Körper validieren
- Name des Vorgangs und Elemente, die in Anforderung und Antwort verfügbar sind
- WS-I-konform
Cons
- WSDL ist aufgrund der zusätzlichen XSD-Definition komplizierter
UDDI
Universal Description, Discovery and Integration (UDDI)
ist eine offene Brancheninitiative aus dem Jahr 2000, die als XML-basierte Yellow-Pages-Registrierung für Webservices fungiert und dabei hilft, Services zu finden, die bestimmte Aufgaben lösen. Um einen geeigneten Dienst zu finden, muss ein Dienst zuerst bei einer Web-Service-Registry wie dem UDDI registriert werden.
UDDI arbeitet mit dem SOAP-Nachrichtenaustausch und bietet Zugriff auf WSDL-Dokumente, mit denen der eigentliche Webdienst aufgerufen werden kann.
Die UDDI bietet Suchkriterien wie
- Geschäftskennung
- Firmenname
- Geschäftsstandort
- Geschäftskategorie
- Servicetyp nach Name
- Discovery-URLs
Ein großer Nachteil der aktuellen UDDI ist jedoch, dass nur ein einziges Kriterium innerhalb einer Suchanweisung verwendet werden kann. Bestimmte Implementierer haben daher ihre UDDI-Implementierungen modularisiert, um Abfragen zu ermöglichen, die mehrere UDDIs gleichzeitig starten, und die zurückgegebenen Ergebnisse zu aggregieren.
In der Praxis wird UDDI jedoch nicht so häufig verwendet. Einige sagen sogar, UDDI sei tot, seit IBM, Microsoft und SAP ihre UDDI-Dienste 2005 eingestellt hatten .
Weitere Hinweise:
SOAP / WSDL bieten eine breite Palette an Werkzeugunterstützung und ermöglichen auch die dynamische Erzeugung von Stub-Klassen für Clients und Server, da die Art der ausgetauschten Nachrichten und Daten durch die eingebetteten oder verknüpften XSD-Schemata genau definiert wird.
Während WSDL 2.0 weniger Aufwand für die Definition von Webdiensten hat, haben bestimmte Sprachen den neuen Standard noch nicht übernommen. Dh in Java beliebte Tools wie wsimport
(von Oracle / Sun) oder wsdl2java
(von Apache CXF) können WSDL 2.0-Beschreibungen nicht ordnungsgemäß verarbeiten. Aus Kompatibilitätsgründen wird daher weiterhin empfohlen, WSDL 1.1 zu verwenden. Wenn Sie einen WSDL 2.0-basierten SOAP-Dienst in Java entwickeln müssen, schauen Sie sich wsdl2java
aus dem Apache Axis2- Projekt an.
Heutzutage beliebter sind jedoch entweder HTTP-basierte API-Dienste, die HTTP-Operationsaufrufe mit sauber verständlichen URIs und bestimmten Anpassungen des Protokolls kombinieren, um ihre Arbeit zu erledigen, REST- basierte Dienste, die vollständig den tatsächlichen Empfehlungen entsprechen. oder eigene Protokolle auf Byte-Ebene, wie zB OFTP2 .
SOAP ist heutzutage immer noch nützlich, wenn Sie Ihre Aufgabe nicht direkt Ressourcen zuordnen können, wie dies bei HTTP / REST-Basisdiensten der Fall ist. Die auszuführende Aufgabe stellt natürlich eine Aktion dar oder muss bestimmte Transaktionssemantiken definieren. Wenn Sie nicht über die Ressourcen zum Definieren oder Implementieren Ihres eigenen Protokolls verfügen, ist es wahrscheinlich besser, SOAP zu verwenden. SOAP ist besonders nützlich, wenn Sie sich mit Orchestrierung befassen müssen, da die WSDL-Beschreibung in Kombination mit UDDI das dynamische Kombinieren von Diensten ermöglicht.
Open-Source-Webservice für Java-Client für Wetterdienst verfügbar unter http://www.webserviceX.NET
package com.test.ws.example;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
/*
* WSDL url : http://www.webservicex.com/globalweather.asmx?WSDL
* Endpoint URL: http://www.webservicex.com/globalweather.asmx */
public class WSClient {
public static void main(String args[]) {
try {
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
// Generate SOAP request XML
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders header = soapMessage.getMimeHeaders();
header.setHeader("SOAPAction", "http://www.webserviceX.NET/GetCitiesByCountry");
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("web", "http://www.webserviceX.NET");
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("GetCitiesByCountry", "web");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("CountryName", "web");
soapBodyElem1.addTextNode("INDIA");
soapMessage.saveChanges();
soapMessage.writeTo(System.out);
// Call webservice endpint
String url = "http://www.webservicex.com/globalweather.asmx";
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
Source sourceContent = soapResponse.getSOAPPart().getContent();
// Print SOAP response
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
System.out.println("Response SOAP Message \n");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
soapConnection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Erstellen eines einfachen Web-Service und Clients mit JAX-WS (Dokument / Literal)
Dies ist das Projektverzeichnis.
- Eine Service-Endpunkt-Schnittstelle
Zuerst erstellen wir eine Service-Endpunkt-Schnittstelle. Die Annotation javax.jws.WebService @WebService
definiert die Klasse als Web-Service-Endpunkt.
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
// Service Interface with customize targetNamespace
@WebService(targetNamespace = "http://hello-soap/ws")
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL) //optional
public interface HelloSoap {
@WebMethod String getHelloSoap(String name);
}
- Service Endpoint-Implementierung (SEI)
Als Nächstes erstellen wir eine Service-Endpunkt-Implementierung. Wir werden eine explizite Schnittstelle durch Hinzufügen des erstellen endpointInterface
Element zum @WebService
Anmerkung in der Implementierungsklasse. Hier einige Regeln 28.1.1 Anforderungen an einen JAX-WS-Endpunkt , an die sich JAX-WS-Endpunkte halten müssen. Die getHelloSoap-Methode gibt eine Begrüßung mit dem übergebenen Namen an den Client zurück.
import javax.jws.WebService;
// Customized Service Implementation (portName,serviceName,targetNamespace are optional)
@WebService(portName = "HelloSoapPort", serviceName = "HelloSoapService",
endpointInterface = "com.wonderland.hellosoap.HelloSoap", targetNamespace = "http://hello-soap/ws")
public class HelloSoapImpl implements HelloSoap {
@Override
public String getHelloSoap(String name) {
return "[JAX-WS] Hello : " + name;
}
}
- Herausgeber des Web-Service-Endpunkts
import javax.xml.ws.Endpoint;
public class HelloSoapPublisher {
public static void main(String[] args) {
// creating web service endpoint publisher
Endpoint.publish("http://localhost:9000/ws/hello-soap", new HelloSoapImpl());
}
}
- Als nächstes führen wir
HelloSoapPublisher.java
als Java-Anwendung aus. Anschließend können Sie die WSDL-Dateihttp://localhost:9000/ws/hello-soap?wsdl
in einem Webbrowser die URLhttp://localhost:9000/ws/hello-soap?wsdl
.
http: // localhost: 9000 / ws / hallo-soap? wsdl
Wenn das XML-Datenformat im Webbrowser angezeigt wird, können Sie mit dem nächsten Schritt fortfahren.
Hinweis:
Wenn Sie eine Fehlermeldung erhalten, müssen Sie möglicherweise daswsgen
Tool verwenden, um die erforderlichen tragbaren JAX-WS-Artefakte zu generieren. Wir sind hier nicht über daswsgen
Toolwsgen
.
- Web Service Client
Abschließend erstellen wir einen Client, der auf unseren veröffentlichten Service zugreift.
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
public class HelloSoapClient {
public static void main(String[] args) throws Exception {
// create wsdl url
URL wsdlDocumentUrl = new URL("http://localhost:8000/ws/hello-soap?wsdl");
QName helloSoapService = new QName("http://hello-soap/ws", "HelloSoapService");
// create web service
Service service = Service.create(wsdlDocumentUrl, helloSoapService);
// get object of pointed service port
HelloSoap helloSoap = service.getPort(HelloSoap.class);
// testing request
System.out.println(helloSoap.getHelloSoap("Soap "));
}
}
Ausgabe: [JAX-WS] Hello : Soap
Hinweis: Die 8000
in unserem Webservice-Client auf 8000
geändert. Der Grund hier ist, ich habe Eclipse IDE verwendet, ein eingebautes TCP/IP monitor
Tool, um Nachrichten zu verfolgen . Für Funktionstests versuchen Sie es mit SoapUI | Funktionstest für SOAP- und REST-APIs .