soap Tutorial
Empezando con jabón
Buscar..
Observaciones
Esta sección proporciona una descripción general de qué es el jabón y por qué un desarrollador puede querer usarlo.
También debe mencionar los temas grandes dentro de los jabones, y vincular a los temas relacionados. Dado que la Documentación para soap es nueva, es posible que deba crear versiones iniciales de esos temas relacionados.
Versiones
Versión | Fecha de lanzamiento |
---|---|
1.1 | 2000-05-08 |
1.2 | 2003-06-24 |
Información general
SOAP es un acrónimo de Simple Object Access Protocol que define un protocolo que se utiliza para intercambiar datos a través de una llamada a procedimiento remoto (RPC) con otros servicios o clientes SOAP. Está disponible en dos versiones:
SOAP 1.2 obsoleta SOAP 1.1, por lo tanto, se recomienda utilizar SOAP 1.2 si es posible.
A menudo se construye sobre HTTP / S y rara vez en SMTP o FTP, aunque lo admitiría de acuerdo con el protocolo. Aunque HTTP se usa a menudo como protocolo de transporte subyacente, SOAP usa solo un subconjunto limitado de él. Para enviar solicitudes, se basa casi completamente en la operación POST
de HTTP. GET
invocaciones GET
son teóricamente posibles desde 1.2, aunque el documento debe pasarse como parámetro URI y, por lo tanto, puede superar un límite de aproximadamente 3000 caracteres, que es rechazado por la mayoría de los marcos. Además, la configuración relacionada con la seguridad generalmente se define dentro de un encabezado SOAP especial.
Aunque SOAP y REST se denominan servicios web, son muy diferentes por naturaleza. Algunos marcos distinguen entre WS (para servicios basados en SOAP) y RS (para servicios basados en REST).
La siguiente tabla ofrece una breve descripción general de las diferencias entre ambos tipos de servicios web.
Aspecto | JABÓN | DESCANSO |
---|---|---|
Estándar | Jabón , WSDL | No estándar, solo un estilo arquitectónico. |
Direccionamiento de recursos | Indirecto a través de operaciones SOAP | a través de identificadores de recursos únicos (URI) |
Manejo de errores | Mensaje de error SOAP | Códigos de respuesta de error HTTP y cuerpo de respuesta opcionalmente |
Representación de datos | XML | Todas las codificaciones disponibles en HTTP |
Uso HTTP | Como protocolo de transporte | Acciones en recursos (CRUD) mapeadas en métodos HTTP (GET, POST, PUT, DELETE, ...) |
Soporte transaccional | a través del encabezado SOAP | modelando una transacción como un recurso |
Estado | Con estado (la acción SOAP es parte de la aplicación) | Apátridas (peticiones autocontenidas) |
Descubrimiento de servicio | UDDI / WSDL | Ninguno en realidad Sin embargo, el URI de inicio de la API debería devolver una lista de sub API |
Método | Dentro del cuerpo de jabón | Método HTTP |
Argumentos del método | Definido por el esquema XML en el WSDL | Ya sea a través de los encabezados HTTP o los parámetros de ruta / consulta o matriz dentro del URI |
Transición de estado | Difícil de determinar ya que no se basa directamente en datos | Siguiente invocación de URI |
Soporte de almacenamiento en caché | Caché a menudo no deseado, | Simple según lo definido por HTTP |
JABÓN
Las solicitudes de SOAP consisten en un sobre de SOAP que debe contener un elemento de cuerpo y puede contener un elemento de encabezado opcional. El elemento de encabezado se usa para pasar ciertas configuraciones al servicio, por ejemplo, WS-Security puede definir que el mensaje está cifrado o WS-Coordination / WS-Transaction puede definir que el mensaje debe ejecutarse dentro de una transacción.
Un simple SOAP 1.2 a través de HTTP que agrega dos valores puede tener este aspecto:
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 respuesta a la solicitud de muestra anterior puede verse así
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>
El ejemplo anterior definió una solicitud que invocó el método AddValues
con dos argumentos, FirstValue
establecido en 1
y SecondValue
establecido en 2
. La solicitud dio lugar a una ejecución de este método en el servidor SOAP remoto, que calculó un valor de 3
como un resultado que se encapsula en un elemento de respuesta separado, que por convención suele ser el nombre del método invocado más una cadena de Response
final, por lo que cualquiera que sea inspeccionar la respuesta puede concluir que esta es la respuesta de una invocación previa del método AddValue
.
Diferencias entre SOAP 1.1 y 1.2
SOAP 1.2 permite otros protocolos de transporte, luego HTTP, siempre que el protocolo sea compatible con el marco de enlace.
SOAP 1.1 se basa en XML 1.0, mientras que 1.2 se basa en XML Infoset, que permite serializar los mensajes SOAP con otros serializadores, luego el serializador XML XML predeterminado utilizado por SOAP 1.1. Esto permite, por ejemplo, serializar mensajes como mensajes binarios y, por lo tanto, evitar cierta sobrecarga de la naturaleza XML del mensaje. Además de eso, el mecanismo de serialización del protocolo subyacente utilizado puede determinarse a través del enlace de datos.
El aspecto de interoperabilidad también se fomentó con SOAP 1.2 al definir un modelo de procesamiento más específico y luego su predecesor, lo que eliminó muchas posibilidades de interpretación. SOAP con API adjunta (SAAJ), que permite operar con mensajes SOAP 1.1 y 1.2, ayudó a muchos implementadores de marcos a procesar y crear mensajes.
W3C ha publicado una breve descripción de los principales cambios entre SOAP 1.1 y 1.2
Interoperabilidad de servicios web
La Interoperabilidad del Servicio Web (también conocida como WS-I) es una guía de interoperabilidad gobernada por algunas empresas bien conocidas como IBM, Microsoft, Oracle y HP, por mencionar solo algunas. Estas pautas, entre otras, recomiendan usar solo un único elemento raíz dentro del cuerpo de SOAP, aunque el SOAP permite contener múltiples elementos dentro del cuerpo.
WS-I consiste en
- Perfil básico WS-I también conocido como WSI-BP
- Perfil de seguridad básico WS-I
- Perfil de enlace de jabón simple
WSI-BP está disponible en 4 versiones diferentes v1.0 (2004) , v1.1 (2006) , v1.2 (2010) , v2.0 (2010) y define las pautas de interoperabilidad para las especificaciones de servicios web principales como SOAP, WSDL y UDDI. A través del uso del lenguaje de descripción de servicios web (WSDL), los servicios SOAP pueden describir sus operaciones y métodos compatibles dentro de un conjunto cohesivo a otros puntos finales. WSI-BP utiliza WSDL para definir un conjunto más estrecho, el esquema completo de WSDL o SOAP definiría y, por lo tanto, elimina parte de la ambigüedad dentro de la especificación y, por lo tanto, mejora la interoperabilidad entre los puntos finales.
WSDL
Para anunciar las operaciones SOAP disponibles, sus parámetros, así como los puntos finales respectivos para invocar a los clientes, se usa un documento basado en XML adicional, llamado Web Services Description Language
o WSDL, para abreviar.
WSDL describe el punto final del servicio, la vinculación de los mensajes SOAP a las operaciones, la interfaz de las operaciones y sus tipos a los clientes. WSDL está disponible, como SOAP, en 2 versiones que difieren ligeramente en su sintaxis, aunque expresan casi la misma semántica para el cliente.
WSDL 1.1
Una descripción de WSDL 1.1 contiene un service
, un binding
, un portType
y una sección de message
. Puede importar o definir más esquemas dentro del archivo WSDL como se puede ver en un archivo WSDL de muestra que corresponde a la muestra de la calculadora que se muestra arriba:
<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 sección de service
define los puntos finales concretos en los que el servicio escuchará las solicitudes entrantes. La sección de binding
vincula una operación a un estilo concreto y define qué formatos de mensaje espera el servidor o puede esperar el cliente.
La sección de resumen se compone de un bloque portType
que define las operaciones ofrecidas por el servicio y qué mensajes se intercambian. Los mensajes se especifican en su bloque y están vinculados a los tipos de esquema de los que los argumentos y los valores de retorno son instancias. Los mensajes pueden declarar parámetros o valores de retorno para estar in
, out
o inout
. Mientras que los dos primeros son bastante simples de captar, el segundo imita el comportamiento de los argumentos pasados por referencia. Como no se admite el paso por ref en algunos idiomas, este efecto a menudo se simula a través de ciertos manejadores.
WSDL 2.0
La misma calculadora se puede describir en WSDL 2.0 de esta manera:
<?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>
Diferencias entre WSDL 1.1 y 2.0
En la siguiente imagen se puede ver una descripción gráfica de las diferencias entre ambas versiones.
( Fuente )
Como se puede ver en la imagen, se eliminó la sección del message
, que ahora se encuentra en la sección de la interface
. Además, algunos de los elementos fueron renombrados, otros tienen una sintaxis diferente, pero en general ambas versiones de WSDL hacen básicamente lo mismo, con la versión 2.0 que requiere un poco menos de sobrecarga de escritura en comparación con 1.1.
Además de la huella más pequeña en la definición de servicios basados en SOAP a través de WSDL 2.0, la versión más reciente también brinda capacidades para definir servicios REST, aunque WSDL 2.0 o incluso WADL NO se recomiendan para servicios RESTful, ya que contradicen la idea real detrás de ellos.
¿Qué estilo preferir?
La sección de enlace WSDL describe cómo el servicio está vinculado al protocolo de mensajería SOAP. El ejemplo anterior utilizó el document
como el estilo de enlace, que permite estructurar el cuerpo SOAP de la forma que queramos siempre que la salida resultante sea una instancia XML válida. Este es el estilo de enlace predeterminado y, a menudo, se denomina Message-Oriented style
a Message-Oriented style
.
A diferencia del estilo de document
, los cuerpos de solicitud de estilo RPC
tienen que contener tanto el nombre de la operación como el conjunto de parámetros del método. Por lo tanto, la estructura de la instancia XML está predefinida y no se puede cambiar.
Además del estilo de enlace, la sección de enlace también define un modelo de traducción para enlaces a mensajes SOAP en el nombre de literal
o encoded
. La diferencia entre los dos es que el modelo literal
tiene que ajustarse a una estructura XSD definida por el usuario, que se puede usar para validar las solicitudes y respuestas, mientras que el modelo encoded
tiene que usar tipos de datos XSD como xs:integer
o xs:string
pero a cambio, por lo tanto, no tiene que cumplir con ningún esquema definido por el usuario. Sin embargo, esto hace que sea más difícil validar el cuerpo del mensaje o transformar el mensaje a través de XSLT a otro formato.
La combinación del estilo de enlace con el modelo de uso permite en realidad 4 resultados de mensajes diferentes. Se agrega una quinta entrada a la lista que se usa comúnmente (aunque en realidad no es parte del estándar).
- RPC / codificado
- RPC / literal
- Documento / codificado
- Documento / literal
- Documento / literal (envuelto)
En el documento / estilo de mensajería literal, existe un patrón que se conoce como documento-envuelto / literal. Esto es solo un patrón, y no es parte de la especificación WSDL. Este patrón tiene una mención en JSR 224 (JAX-WS: API de Java para servicios web basados en XML). ( Fuente )
La siguiente sección ofrece una descripción general de las diferencias con respecto a WSDL o la declaración de esquema y su impacto en el formato del mensaje SOAP resultante al cambiar el estilo de enlace o el uso de definiciones de modelo.
RPC / codificado
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' -->
...
Solicitud de 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>
Respuesta de jabón
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result xsi:type="xsd:int">3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Pros
- WSDL sencillo
- Nombre de operación y elementos disponibles en solicitud y respuesta.
Contras
- Declaración explícita de tipos XSI
- Difícil de validar
- No cumple con WS-I
RPC / literal
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' -->
...
Solicitud de SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Respuesta de jabón
<soap:envelope>
<soap:body>
<AddValuesResult>
<Result>3</Result>
</AddValuesResult>
</soap:body>
</soap:envelope>
Pros
- WSDL sencillo
- Nombre de operación y elementos disponibles en solicitud y respuesta.
- No se necesita especificación de tipo XSI
- Cumple con WS-I
Contras
- Difícil de validar
Documento / codificado
No tiene ningún sentido por lo tanto omitido.
Documento / 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' -->
...
Solicitud de SOAP
<soap:envelope>
<soap:body>
<FirstValueElement>1</FirstValueElement>
<SecondValueElement>2</SecondValueElement>
</soap:body>
</soap:envelope>
Respuesta de jabón
<soap:envelope>
<soap:body>
<ResultElement>3</ResultElement>
</soap:body>
</soap:envelope>
Pros
- Sin codificación de tipo XSI
- Capaz de validar cuerpo.
- WS-I cumple con las restricciones
Contras
- WSDL es más complicado debido a la definición adicional de XSD
- Nombre de la operación se pierde
- WS-I solo permite un niño en el cuerpo de SOAP
Documento / literal (envuelto)
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' -->
...
Solicitud de SOAP
<soap:envelope>
<soap:body>
<AddValues>
<FirstValue>1</FirstValue>
<SecondValue>2</SecondValue>
</AddValues>
</soap:body>
</soap:envelope>
Respuesta de jabón
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result>3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
Pros
- Sin codificación de tipo XSI
- Capaz de validar cuerpo.
- Nombre de operación y elementos disponibles en solicitud y respuesta.
- Cumple con WS-I
Contras
- WSDL es más complicado debido a la definición adicional de XSD
UDDI
Universal Description, Discovery and Integration (UDDI)
es una iniciativa de industria abierta creada en 2000 que actúa como un registro de páginas amarillas basado en XML para servicios web que ayuda a encontrar servicios que resuelven tareas específicas. Para encontrar un servicio adecuado, primero se debe registrar un servicio con un Registro de servicios web como el UDDI.
UDDI funciona en el intercambio de mensajes SOAP y proporciona acceso a los documentos WSDL que se pueden usar para invocar el servicio web real.
El UDDI proporciona criterios de búsqueda como
- identificador de negocio
- Nombre del Negocio
- ubicación de la empresa
- categoría de negocios
- tipo de servicio por nombre
- URLs de descubrimiento
Sin embargo, una gran desventaja de la UDDI actual es que solo permite utilizar un único criterio dentro de una declaración de búsqueda. Por lo tanto, algunos implementadores modularizaron sus implementaciones UDDI para permitir consultas que generan múltiples UDDI simultáneamente y luego agregar los resultados devueltos.
En la práctica, sin embargo, UDDI no se utiliza tan a menudo. Algunos incluso dicen que UDDI está muerto desde que IBM, Microsoft y SAP cerraron sus servicios UDDI en 2005 .
Notas adicionales:
SOAP / WSDL proporciona una amplia gama de herramientas de soporte y también permite generar dinámicamente clases de código auxiliar para clientes y servidores, ya que el tipo de mensajes y datos intercambiados están bien definidos a través de los esquemas XSD incrustados o vinculados.
Si bien WSDL 2.0 tiene menos gastos generales para definir servicios web, ciertos idiomas aún no han adoptado el nuevo estándar todavía. Es decir, en las herramientas populares de Java como wsimport
(de Oracle / Sun) o wsdl2java
(de Apache CXF) no son capaces de manejar correctamente las descripciones de WSDL 2.0. Por lo tanto, por razones de compatibilidad, se recomienda usar WSDL 1.1. Si necesita desarrollar un servicio SOAP basado en WSDL 2.0 en Java, eche un vistazo a wsdl2java
del proyecto Apache Axis2 .
Sin embargo, hoy en día son más populares los servicios de API basados en HTTP, que combinan invocaciones de operaciones HTTP con URIs comprensibles para el ser humano y ciertas personalizaciones al protocolo para realizar su trabajo, servicios basados en REST , que cumplen plenamente con las recomendaciones reales. o propios protocolos de nivel de byte, como por ejemplo OFTP2 .
SOAP sigue siendo útil hoy en día si no puede asignar su tarea directamente a los recursos, como hacen los servicios básicos de HTTP / REST, ya que la tarea a cumplir representa naturalmente una acción o tiene que definir cierta semántica de transacción. Además, si no tiene los recursos para definir o implementar su propio protocolo, probablemente sea mejor que use SOAP. SOAP es especialmente útil si tiene que lidiar con la orquestación, ya que la descripción WSDL en combinación con UDDI permite combinar servicios dinámicamente.
Servicio web de código abierto Java Client for Weather service disponible en 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();
}
}
}
Creación de un servicio web simple y clientes con JAX-WS (Documento / literal)
Este es el directorio del proyecto.
- Una interfaz de punto final de servicio
Primero crearemos una interfaz de punto final de servicio. La anotación javax.jws.WebService @WebService
define la clase como un punto final de servicio 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);
}
- Implementación de punto final de servicio (SEI)
A continuación crearemos la implementación del punto final del servicio. Crearemos una interfaz explícita agregando el elemento endpointInterface
a la anotación @WebService
en la clase de implementación. Aquí hay algunos conjuntos de reglas 28.1.1 Requisitos de un punto final de JAX-WS que deben seguir los puntos finales de JAX-WS. El método getHelloSoap devuelve un saludo al cliente con el nombre pasado.
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;
}
}
- Editor de punto final de servicios 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());
}
}
- Los próximos pasos, ejecutaremos
HelloSoapPublisher.java
como aplicación java. Luego veremos el archivo WSDL solicitando la URLhttp://localhost:9000/ws/hello-soap?wsdl
en un navegador web.
http: // localhost: 9000 / ws / hello-soap? wsdl
Si el formato de datos XML se muestra en el navegador web, entonces estamos listos para continuar con el siguiente paso.
Nota:
Si recibe algún tipo de mensaje de error, tal vez necesite usar la herramientawsgen
para generar los artefactos portátiles JAX-WS necesarios. No estamos cubiertos acerca de la herramientawsgen
aquí.
- Cliente de servicio web
Paso final, crearemos un cliente que acceda a nuestro servicio publicado.
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 "));
}
}
Salida: [JAX-WS] Hello : Soap
Nota: El número de puerto cambió a 8000
en nuestro cliente de servicio web. La razón aquí es que usé Eclipse IDE, una herramienta de TCP/IP monitor
para rastrear mensajes (Más información: Cómo rastrear el mensaje SOAP en Eclipse IDE ) Para propósitos de prueba funcional prueba SoapUI | Pruebas funcionales para APIs de SOAP y REST .