soap Tutorial
Iniziare con il sapone
Ricerca…
Osservazioni
Questa sezione fornisce una panoramica di cosa sia il sapone e perché uno sviluppatore potrebbe volerlo utilizzare.
Dovrebbe anche menzionare eventuali soggetti di grandi dimensioni all'interno di soap e collegarsi agli argomenti correlati. Poiché la Documentazione per il sapone è nuova, potrebbe essere necessario creare versioni iniziali di tali argomenti correlati.
Versioni
Versione | Data di rilascio |
---|---|
1.1 | 2000/05/08 |
1.2 | 2003-06-24 |
Informazione generale
SOAP è un acronimo di Simple Object Access Protocol che definisce un protocollo utilizzato per lo scambio di dati tramite Remote Procedure Call (RPC) con altri servizi o client SOAP. È disponibile in due versioni:
SOAP 1.2 obsoletes SOAP 1.1 è quindi consigliabile utilizzare SOAP 1.2 se possibile.
È spesso costruito su HTTP / S e raramente su SMTP o FTP, sebbene lo supporti in base al protocollo. Sebbene HTTP sia spesso utilizzato come protocollo di trasporto sottostante, SOAP utilizza solo un sottoinsieme limitato di esso. Per l'invio di richieste si basa quasi completamente sull'operazione POST
di HTTP. GET
invocazioni GET
sono teoricamente possibili da 1.2, anche se il documento deve essere passato come parametro URI e quindi può superare un limite di circa 3000 caratteri che viene rifiutato dalla maggior parte dei framework. Inoltre, le impostazioni relative alla sicurezza vengono generalmente definite all'interno di un'intestazione SOAP speciale.
Sebbene SOAP e REST siano chiamati servizi Web, sono molto diversi per loro natura. Alcuni framework distinguono tra WS (per servizi basati su SOAP) e RS (per servizi basati su REST).
La seguente tabella fornisce una breve panoramica delle differenze tra i due tipi di servizi Web.
Aspetto | SAPONE | RIPOSO |
---|---|---|
Standard | SAPONE , WSDL | Nessun standard, solo uno stile architettonico |
Indirizzamento delle risorse | Indiretto tramite operazioni SOAP | tramite identificatori di risorse univoci (URI) |
Gestione degli errori | Messaggio di errore SOAP | Codici di risposta all'errore HTTP e facoltativamente corpo della risposta |
Rappresentazione dei dati | XML | tutte le codifiche disponibili in HTTP |
Utilizzo HTTP | Come protocollo di trasporto | Azioni su risorse (CRUD) mappate su metodi HTTP (GET, POST, PUT, DELETE, ...) |
Supporto transazionale | tramite l'intestazione SOAP | modellando una transazione come risorsa |
Stato | Stateful (l'azione SOAP è parte dell'applicazione) | Stateless (richieste autonome) |
Scoperta del servizio | UDDI / WSDL | Nessuno in realtà; L'URI iniziale dell'API dovrebbe restituire comunque un elenco di API secondarie |
Metodo | All'interno del corpo SOAP | Metodo HTTP |
Argomenti del metodo | Definito dallo schema XML nel WSDL | Tramite i parametri HTTP Headers o Path / Query o Matrix nell'URI |
Transizione di stato | Difficile determinare come non direttamente basato sui dati | Prossima chiamata URI |
Supporto di cache | Caching spesso non desiderato, | Semplice come definito da HTTP |
SAPONE
Una richiesta SOAP consiste in un envelope SOAP che deve contenere un elemento body e può contenere un elemento header opzionale. L'elemento header viene utilizzato per passare determinate configurazioni al servizio, ad esempio WS-Security può definire che il messaggio è crittografato o WS-Coordination / WS-Transaction può definire che il messaggio deve essere eseguito all'interno di una transazione.
Una semplice richiesta di SOAP 1.2 via HTTP che aggiunge due valori può essere così:
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>
Una risposta alla richiesta di esempio sopra può apparire come questa
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>
L'esempio precedente ha definito una richiesta che ha invocato il metodo AddValues
con due argomenti, FirstValue
impostato su 1
e SecondValue
impostato su 2
. La richiesta ha comportato un'esecuzione di questo metodo sul server SOAP remoto che ha calcolato un valore di 3
come risultato incapsulato in un elemento di risposta separato, che per convenzione è spesso il nome del metodo richiamato più una stringa di Response
finale, quindi chiunque sia l'ispezione della risposta può concludere che questa è la risposta di una precedente AddValue
metodo AddValue
.
Differenze tra SOAP 1.1 e 1.2
SOAP 1.2 consente altri protocolli di trasporto quindi HTTP purché il framework di binding sia supportato dal protocollo.
SOAP 1.1 è basato su XML 1.0, mentre 1.2 è basato su Infoset XML che consente di serializzare i messaggi SOAP con altri serializzatori, quindi il serializzatore XML 1.0 predefinito utilizzato da SOAP 1.1. Ciò consente, ad esempio, di serializzare i messaggi come messaggi binari e quindi di evitare un sovraccarico della natura XML del messaggio. In aggiunta a ciò, il meccanismo di serializzazione del protocollo sottostante utilizzato può essere determinato tramite l'associazione dati.
L'aspetto dell'interoperabilità è stato anche promosso con SOAP 1.2 definendo un modello di elaborazione più specifico del suo predecessore che ha eliminato molte possibilità di interpretazione. SOAP with Attachment API (SAAJ), che consente di operare sui messaggi SOAP 1.1 e 1.2, ha aiutato molti implementatori di framework a elaborare e creare messaggi.
W3C ha rilasciato una breve panoramica sulle principali modifiche tra SOAP 1.1 e 1.2
Interoperabilità del servizio Web
Interoperabilità del servizio Web (noto anche come WS-I) è una linea guida di interoperabilità governata da alcune ben note aziende come IBM, Microsoft, Oracle e HP per citarne solo alcuni. Queste linee guida consigliano tra l'altro di utilizzare un solo elemento radice all'interno del corpo SOAP anche se il SOAP consente di contenere più elementi all'interno del corpo.
WS-I consiste di
- Profilo di base WS-I noto anche come WSI-BP
- WS-I Profilo di sicurezza di base
- Profilo semplice di legame del sapone
WSI-BP è disponibile in 4 versioni diverse v1.0 (2004) , v1.1 (2006) , v1.2 (2010) , v2.0 (2010) e definisce le linee guida di interoperabilità per le specifiche del servizio web principale come SOAP, WSDL e UDDI. Tramite l'utilizzo del WSDL (Web Services Description Language), i servizi SOAP possono descrivere le operazioni e i metodi supportati all'interno di un set coesivo su altri endpoint. WSI-BP utilizza WSDL per definire un set più ristretto, quindi lo schema WSDL o SOAP completo definirà e quindi eliminerà alcune delle ambiguità all'interno della specifica stessa, migliorando così l'interoperabilità tra gli endpoint.
WSDL
Per pubblicizzare le operazioni SOAP disponibili, i relativi parametri e i rispettivi endpoint da richiamare ai client, viene utilizzato un ulteriore documento basato su XML denominato Web Services Description Language
o WSDL.
WSDL descrive l'endpoint del servizio, l'associazione dei messaggi SOAP alle operazioni, l'interfaccia delle operazioni e i loro tipi ai client. WSDL è, come SOAP, disponibile in 2 versioni che differiscono leggermente nella loro sintassi, sebbene esprimano quasi la stessa semantica del client.
WSDL 1.1
Una descrizione di WSDL 1.1 contiene un service
, un binding
, una portType
e una sezione di message
. Può inoltre importare o definire schemi all'interno del file WSDL come può essere visto da un file WSDL di esempio che corrisponde all'esempio della calcolatrice mostrato sopra:
<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>
Una sezione di service
definisce gli endpoint concreti che il servizio ascolterà per le richieste in entrata. La sezione di binding
associa un'operazione a uno stile concreto e definisce i formati di messaggio che il server si aspetta o il client può aspettarsi.
La sezione astratta è composta da un blocco portType
che definisce le operazioni offerte dal servizio e quali messaggi vengono scambiati. I messaggi sono specificati nel loro blocco on e collegati ai tipi di schema, gli argomenti e i valori restituiti sono istanze di. I messaggi possono dichiarare parametri o restituire valori in
inout
, in out
o inout
. Mentre i primi due sono abbastanza semplici da comprendere, quest'ultimo imita il comportamento degli argomenti passati per riferimento. Poiché il pass-by-ref non è supportato in alcune lingue, questo effetto viene spesso simulato tramite alcuni gestori.
WSDL 2.0
La stessa calcolatrice può essere descritta in WSDL 2.0 in questo modo:
<?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>
Differenze tra WSDL 1.1 e 2.0
Nell'immagine seguente è disponibile una panoramica grafica delle differenze tra le due versioni.
( Fonte )
Come si può vedere dall'immagine, la sezione del message
è stata rimossa e ora è contenuta nella sezione interface
. Inoltre, alcuni degli elementi sono stati rinominati, altri hanno una sintassi diversa, ma in generale entrambe le versioni di WSDL fanno sostanzialmente la stessa cosa con la versione 2.0 che richiede un overhead di scrittura un po 'inferiore rispetto a 1.1.
Oltre all'ingombro ridotto sulla definizione dei servizi basati su SOAP tramite WSDL 2.0, la versione più recente fornisce anche funzionalità per definire i servizi REST anche se WSDL 2.0 o anche WADL NON sono raccomandati per i servizi RESTful in quanto contraddicono l'idea reale alla base.
Quale stile preferire
La sezione di collegamento WSDL descrive in che modo il servizio è associato al protocollo di messaggistica SOAP. L'esempio precedente ha utilizzato il document
come stile di associazione, che consente di strutturare il corpo SOAP nel modo desiderato, purché l'output risultante sia un'istanza XML valida. Questo è lo stile di associazione predefinito e spesso definito come Message-Oriented style
ai Message-Oriented style
.
Al contrario dello stile del document
, i corpi delle richieste di stile RPC
devono contenere sia il nome dell'operazione sia l'insieme dei parametri del metodo. La struttura dell'istanza XML è quindi predefinita e non può essere modificata.
Oltre allo stile di associazione, la sezione di associazione definisce anche un modello di traduzione per i collegamenti ai messaggi SOAP nel nome literal
o encoded
. La differenza tra i due è che quel modello literal
deve conformarsi a una struttura XSD definita dall'utente, che può essere usata per convalidare le richieste e le risposte, mentre il modello encoded
deve usare i tipi di dati XSD come xs:integer
o xs:string
ma in cambio quindi non deve conformarsi a nessuno schema definito dall'utente. Ciò tuttavia rende più difficile convalidare il corpo del messaggio o trasformare il messaggio tramite XSLT in un altro formato.
La combinazione dello stile di rilegatura con il modello d'uso consente di ottenere effettivamente 4 risultati diversi del messaggio. Una quinta voce viene aggiunta alla lista che è comunemente usata (sebbene non faccia realmente parte dello standard).
- RPC / codificato
- RPC / letterale
- Documento / codificato
- Documento / letterale
- Documento / letterale (incartato)
Nello stile di messaggistica documentale / letterale esiste un modello noto come wrapped-document / literal. Questo è solo uno schema e non fa parte delle specifiche WSDL. Questo schema è menzionato in JSR 224 (JAX-WS: API Java per servizi Web basati su XML). ( Fonte )
La seguente sezione offre una panoramica delle differenze relative alla dichiarazione WSDL o allo schema e al loro impatto sul formato di messaggio SOAP risultante sulla modifica dello stile di associazione o delle definizioni del modello di utilizzo.
RPC / codificato
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' -->
...
Richiesta SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue xsi:type="xsd:int">1</FirstValue>
<SecondValue xsi:type="xsd:int">2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Risposta SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result xsi:type="xsd:int">3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Professionisti
- semplice WSDL
- Nome dell'operazione e elementi disponibili in richiesta e risposta
Contro
- Dichiarazione esplicita di tipi XSI
- Difficile da convalidare
- Non conforme a WS-I
RPC / letterale
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' -->
...
Richiesta SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Risposta SOAP
<soap:envelope>
<soap:body>
<AddValuesResult>
<Result>3</Result>
</AddValuesResult>
</soap:body>
</soap:envelope>
Professionisti
- semplice WSDL
- Nome dell'operazione e elementi disponibili in richiesta e risposta
- Non sono necessarie specifiche di tipo XSI
- WS-I compliant
Contro
- Difficile da convalidare
Documento / codificato
Non ha alcun senso quindi omesso.
Documento / letterale
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' -->
...
Richiesta SOAP
<soap:envelope>
<soap:body>
<FirstValueElement>1</FirstValueElement>
<SecondValueElement>2</SecondValueElement>
</soap:body>
</soap:envelope>
Risposta SOAP
<soap:envelope>
<soap:body>
<ResultElement>3</ResultElement>
</soap:body>
</soap:envelope>
Professionisti
- Nessuna codifica del tipo XSI
- In grado di convalidare il corpo
- WS-I conforme alle restrizioni
Contro
- WSDL è più complicato a causa della definizione XSD aggiuntiva
- Il nome dell'operazione è perso
- WS-I consente solo un bambino nel corpo SOAP
Documento / letterale (incartato)
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' -->
...
Richiesta SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Risposta SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result>3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Professionisti
- Nessuna codifica del tipo XSI
- In grado di convalidare il corpo
- Nome dell'operazione e elementi disponibili in richiesta e risposta
- WS-I compliant
Contro
- WSDL è più complicato a causa della definizione XSD aggiuntiva
UDDI
Universal Description, Discovery and Integration (UDDI)
è un'iniziativa di settore aperta creata nel 2000 che funge da registro di pagine gialle basato su XML per i servizi Web che aiuta a trovare servizi che risolvono compiti specifici. Per trovare un servizio appropriato, è necessario prima registrare un servizio con un registro dei servizi Web come UDDI.
UDDI funziona sullo scambio di messaggi SOAP e fornisce l'accesso ai documenti WSDL che possono essere utilizzati per richiamare il servizio web effettivo.
L'UDDI fornisce criteri di ricerca come
- identificatore di business
- Nome commerciale
- posizione commerciale
- Categoria di Business
- tipo di servizio per nome
- URL di scoperta
Tuttavia, un grande svantaggio dell'attuale UDDI è che consente solo di utilizzare un singolo criterio all'interno di un'istruzione di ricerca. Alcuni implementatori pertanto hanno modularizzato le loro implementazioni UDDI per consentire le query che generano contemporaneamente più UDDI e quindi aggregano i risultati restituiti.
In pratica, tuttavia, l'UDDI non viene usato così spesso. Alcuni dicono addirittura che UDDI è morto da quando IBM, Microsoft e SAP hanno chiuso i loro servizi UDDI nel 2005 .
Ulteriori note:
SOAP / WSDL fornisce un'ampia gamma di supporto per gli strumenti e consente anche di generare dinamicamente stub-classes per client e server in quanto il tipo di messaggi e di dati scambiati è ben definito attraverso gli schemi XSD incorporati o collegati.
Mentre WSDL 2.0 ha meno spese generali per la definizione dei servizi Web, alcune lingue non hanno ancora adottato il nuovo standard. Ie in Java strumenti popolari come wsimport
(da Oracle / Sun) o wsdl2java
(da Apache CXF) non sono in grado di gestire correttamente le descrizioni WSDL 2.0. Pertanto, per motivi di compatibilità si consiglia comunque di utilizzare WSDL 1.1. Se è necessario sviluppare un servizio SOAP basato su WSDL 2.0 in Java, consultare wsdl2java
dal progetto Apache Axis2 .
Al giorno d'oggi più popolari sono servizi API basati su HTTP, che combinano invocazioni di operazioni HTTP con URI puliti comprensibili all'uomo e alcune personalizzazioni al protocollo per svolgere il proprio lavoro, servizi basati su REST , che soddisfano pienamente le raccomandazioni effettive, o possedere protocolli a livello di byte, come ad esempio OFTP2 .
SOAP è ancora utile oggigiorno se non è possibile mappare l'attività direttamente alle risorse, come fanno i servizi di base di HTTP / REST, poiché l'attività da eseguire rappresenta naturalmente un'azione o deve definire una certa semantica della transazione. Inoltre, se non si dispone delle risorse per definire o implementare il proprio protocollo, è preferibile utilizzare SOAP. SOAP è particolarmente utile se si ha a che fare con l'orchestrazione poiché la descrizione WSDL in combinazione con UDDI consente di combinare i servizi in modo dinamico.
Servizio client open source di Java Client for Weather disponibile su 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();
}
}
}
Creazione di un servizio Web semplice e client con JAX-WS (documento / letterale)
Questa è la directory del progetto.
- Un'interfaccia endpoint di servizio
Per prima cosa creeremo un'interfaccia per l'endpoint del servizio. L'annotazione javax.jws.WebService @WebService
definisce la classe come un endpoint del servizio Web.
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);
}
- Implementazione degli endpoint di servizio (SEI)
Successivamente creeremo l'implementazione dell'endpoint del servizio. Creeremo un'interfaccia esplicita aggiungendo l'elemento endpointInterface
all'annotazione @WebService
nella classe di implementazione. Ecco alcune serie di regole 28.1.1 Requisiti di un endpoint JAX-WS che gli endpoint JAX-WS devono seguire. Il metodo getHelloSoap restituisce un saluto al client con il nome passato ad esso.
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;
}
}
- Editore di endpoint del servizio Web
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());
}
}
- I prossimi passi, eseguiremo
HelloSoapPublisher.java
come applicazione java. Quindi visualizzeremo il file WSDL richiedendo l'URLhttp://localhost:9000/ws/hello-soap?wsdl
in un browser web.
http: // localhost: 9000 / ws / ciao-soap WSDL
Se il formato dei dati XML è visualizzato sul browser Web, siamo pronti per procedere al passaggio successivo.
Nota:
Se ricevi una sorta di messaggio di errore, forse devi usarewsgen
strumentowsgen
per generare gli artefatti portatili necessari di JAX-WS. Non ciwsgen
strumentowsgen
qui.
- Client servizio Web
Passaggio finale, creeremo un client che accede al nostro servizio pubblicato.
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 "));
}
}
Uscita: [JAX-WS] Hello : Soap
Nota: il numero di porta è cambiato in 8000
nel nostro client di servizi Web. Il motivo è che ho usato Eclipse IDE, strumento di TCP/IP monitor
per tracciare i messaggi (Ulteriori informazioni: Come tracciare il messaggio SOAP in Eclipse IDE ). Per scopi di test funzionali, prova SoapUI | Test funzionali per API SOAP e REST .