Empezando con el jabón
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 deja obsoleto a SOAP 1.1, por lo que se recomienda utilizar SOAP 1.2 si es posible.
A menudo se basa en 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 este. Para enviar solicitudes, se basa casi por completo en la operación POST
de HTTP. Las invocaciones GET
son teóricamente posibles desde 1.2, aunque el documento debe pasarse como parámetro URI y, por lo tanto, puede exceder 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 de naturaleza muy diferente. 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 | SOAP, WSDL | Sin 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 de SOAP | Códigos de respuesta de error HTTP y, opcionalmente, cuerpo de respuesta |
Representación de datos | XML | todas las codificaciones disponibles en HTTP |
Uso de HTTP | Como protocolo de transporte | Acciones sobre recursos (CRUD) mapeadas sobre 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 (solicitudes independientes) |
Descubrimiento de servicios | UDDI / WSDL | Ninguno en realidad; Sin embargo, la URI de inicio de la API debería devolver una lista de sub API |
Método | Interior del cuerpo SOAP | método HTTP |
Argumentos del método | Definido por el esquema XML en el WSDL | Ya sea a través de encabezados HTTP o parámetros de ruta/consulta o matriz dentro del URI |
Transición estatal | Difícil de determinar ya que no se basa directamente en los datos | Siguiente invocación de URI |
Soporte de almacenamiento en caché | Almacenamiento en caché a menudo no deseado, | Simple como lo define HTTP |
JABÓN
Una solicitud SOAP consta de un sobre 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] (https://en.wikipedia.org/wiki/WS-Security) puede definir que el mensaje está encriptado o WS-Coordination/WS -Transaction puede definir que el mensaje debe ejecutarse dentro de una transacción.
Una solicitud SOAP 1.2 simple a través de HTTP que agrega dos valores puede verse así:
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 resultó en una ejecución de este método en el
servidor SOAP remoto que calculó un valor de ‘3’ como 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 ‘Respuesta’ final para que cualquiera que esté inspeccionando la respuesta pueda concluir que esto 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 además de HTTP, siempre que el marco de enlace sea compatible con el protocolo.
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 que el serializador XML 1.0 predeterminado utilizado por SOAP 1.1. Esto permite, por ejemplo, serializar mensajes como mensajes binarios y, por lo tanto, evitar algunos gastos generales de la naturaleza XML del mensaje. Además de eso, el mecanismo de serialización del protocolo subyacente utilizado se puede determinar a través del enlace de datos.
El aspecto de la interoperabilidad también se fomentó con SOAP 1.2 al definir un modelo de procesamiento más específico que su predecesor, lo que eliminó muchas posibilidades de interpretación. SOAP con API de archivos adjuntos (SAAJ), que permite operar en 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 general de los principales cambios entre SOAP 1.1 y 1.2] (https://www.w3.org/2003/06/soap11-soap12.html)
Interoperabilidad de servicios web
[Interoperabilidad de servicios web (también conocida como WS-I)] (https://en.wikipedia.org/wiki/Web_Services_Interoperability) es una guía de interoperabilidad regida por algunas empresas conocidas como IBM, Microsoft, Oracle y HP, por nombrar solo algunos. Estas pautas, entre otras, recomiendan usar solo un único elemento raíz dentro del cuerpo SOAP, aunque SOAP permite contener múltiples elementos dentro del cuerpo.
WS-I consta de
- Perfil básico de WS-I, también conocido como WSI-BP
- Perfil de seguridad básico WS-I
- Perfil de encuadernación de jabón simple
WSI-BP está disponible en 4 versiones diferentes v1.0 (2004), v1.1 ( 2006), [v1.2 (2010)](http://ws-i.org/profiles/BasicProfile-1.2- 2010-11-09.html), v2.0 (2010) y define las pautas de interoperabilidad para el servicio web central especificaciones como SOAP, WSDL y UDDI. Mediante el uso del lenguaje de descripción de servicios web (WSDL), los servicios SOAP pueden describir sus operaciones y métodos admitidos dentro de un conjunto cohesivo para otros puntos finales. WSI-BP utiliza WSDL para definir un conjunto más limitado que el que definiría el esquema WSDL o SOAP completo y, por lo tanto, elimina parte de la ambigüedad dentro de la especificación misma y, por lo tanto, mejora la interoperabilidad entre puntos finales.
#WSDL
Para anunciar las operaciones SOAP disponibles, sus parámetros, así como los puntos finales respectivos para invocar a los clientes, se utiliza otro documento basado en XML llamado “Lenguaje de descripción de servicios web” o WSDL para abreviar.
WSDL describe el punto final del servicio, el enlace de los mensajes SOAP a las operaciones, la interfaz de las operaciones y sus tipos para los clientes. WSDL, como SOAP, está disponible 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 una sección de servicio
, enlace
, tipo de puerto
y mensaje
.
Puede importar o definir 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 servicio
define los puntos finales concretos que el servicio escuchará para las solicitudes entrantes. La sección binding
vincula una operación a un estilo concreto y define qué formatos de mensaje espera el servidor o el cliente puede esperar.
La sección abstracta se compone de un bloque portType
que define las operaciones que ofrece el servicio y qué mensajes se intercambian. Los mensajes se especifican en su bloque on y se vinculan a los tipos de esquema de los que los argumentos y los valores devueltos son instancias. Los mensajes pueden declarar parámetros o devolver valores para ser in
, out
o inout
. Mientras que los dos primeros son bastante simples de comprender, el último imita el comportamiento de los argumentos pasados por referencia. Como pass-by-ref no es compatible con algunos idiomas, este efecto a menudo se simula a través de ciertos controladores.
##WSDL 2.0
La misma calculadora se puede describir en WSDL 2.0 así:
<?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](http://www.wideskills.com/wsdl/differences- between-wsdl-20-and-wsdl-11))
Como se puede ver en la imagen, se eliminó la sección “mensaje”, que ahora está contenida en la sección “interfaz”. Además, se cambió el nombre de algunos de los elementos, otros tienen una sintaxis diferente pero, en general, ambas versiones de WSDL hacen básicamente lo mismo que la versión 2.0, que requiere un poco menos de sobrecarga de escritura en comparación con la 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 nueva también proporciona [capacidades para definir servicios REST] (http://www.ibm.com/developerworks/library/ws-restwsdl/) a través de WSDL 2.0 o incluso WADL NO se recomiendan para servicios RESTful ya que contradicen la idea real detrás de esto.
Qué estilo preferir
La sección de vinculación de WSDL describe cómo se vincula el servicio al protocolo de mensajería SOAP. El ejemplo anterior usó document
como estilo de enlace, lo que permite estructurar el cuerpo SOAP de la manera
queramos, siempre que la salida resultante sea una instancia XML válida. Este es el estilo de encuadernación predeterminado y, a menudo, se denomina “estilo orientado a mensajes”.
A diferencia del estilo document
, los cuerpos de solicitud de estilo RPC
deben 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 vinculación, la sección de vinculación también define un modelo de traducción para vinculaciones a mensajes SOAP con el nombre de “literal” o “codificado”. 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 ‘codificado’ tiene que usar tipos de datos XSD como ‘xs:integer o
xs:string` pero, a cambio, no tiene que ajustarse a 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 mediante 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 estilo de mensajería de documento/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: Java API para servicios web basados en XML). (Fuente)
La siguiente sección ofrece una descripción general de las diferencias con respecto a WSDL o declaración de esquema y su impacto en el formato de mensaje SOAP resultante al cambiar el estilo de vinculación o las definiciones de modelo de uso.
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 SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result xsi:type="xsd:int">3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
ventajas
- WSDL sencillo
- Nombre de la 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 SOAP
<soap:envelope>
<soap:body>
<AddValuesResult>
<Result>3</Result>
</AddValuesResult>
</soap:body>
</soap:envelope>
ventajas
- WSDL sencillo
- Nombre de la 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 que se omite.
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 SOAP
<soap:envelope>
<soap:body>
<ResultElement>3</ResultElement>
</soap:body>
</soap:envelope>
ventajas
- Sin codificación de tipo XSI
- Capaz de validar el cuerpo
- WS-I compatible con restricciones
Contras
- WSDL es más complicado debido a la definición XSD adicional
- Se pierde el nombre de la operación
- WS-I solo permite un niño en el cuerpo 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 SOAP
<soap:envelope>
<soap:body>
<AddValuesResponse>
<Result>3</Result>
</AddValuesResponse>
</soap:body>
</soap:envelope>
ventajas
- Sin codificación de tipo XSI
- Capaz de validar el cuerpo
- Nombre de la operación y elementos disponibles en solicitud y respuesta
- Cumple con WS-I
Contras
- WSDL es más complicado debido a la definición XSD adicional
#UDDI
‘Universal Description, Discovery and Integration (UDDI)’ es una iniciativa industrial 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 en un Registro de servicios web como UDDI.
UDDI funciona en el intercambio de mensajes SOAP y brinda acceso a documentos WSDL que se pueden usar para invocar el servicio web real.
El UDDI proporciona criterios de búsqueda como
- identificador comercial
- Nombre del Negocio
- ubicación de la empresa
- categoría de negocios
- tipo de servicio por nombre
- URL de descubrimiento
Sin embargo, una gran desventaja del UDDI actual es que solo permite usar un solo criterio dentro de una declaración de búsqueda. Ciertos implementadores, por lo tanto, modularizaron sus implementaciones de UDDI para permitir que las consultas generaran múltiples UDDI simultáneamente y luego agregaran los resultados devueltos.
En la práctica, sin embargo, UDDI no se usa con tanta frecuencia. Algunos incluso dicen que UDDI está muerto desde que IBM, Microsoft y SAP [cerraron sus servicios UDDI en 2005] (https://web.archive.org/web/20070704154230/http://www.theserverside.net/news/ subproceso.tss?thread_id=38136).
Notas adicionales:
SOAP/WSDL proporciona una amplia gama de soporte de herramientas y también permite generar dinámicamente clases auxiliares tanto para clientes como para servidores, ya que el tipo de mensajes y datos intercambiados está bien definido a través de los esquemas XSD integrados o vinculados.
Si bien WSDL 2.0 tiene menos gastos generales para definir servicios web, ciertos lenguajes aún no han adoptado el nuevo estándar. Es decir. en Java, las herramientas populares como wsimport
(de Oracle/Sun) o wsdl2java
(de Apache CXF) no pueden manejar las descripciones de WSDL 2.0 correctamente. Por lo tanto, por motivos de compatibilidad, todavía se recomienda utilizar WSDL 1.1. Si necesita desarrollar un servicio SOAP basado en WSDL 2.0 en Java, eche un vistazo al proyecto wsdl2java
del Apache Axis2.
Sin embargo, hoy en día son más populares los servicios API basados en HTTP, que combinan invocaciones de operaciones HTTP con URI limpios y comprensibles para los humanos y ciertas personalizaciones del protocolo para realizar su trabajo, servicios basados en REST, que cumplen plenamente a las recomendaciones reales, o protocolos de nivel de byte propios, como, por ejemplo, [OFTP2] (https://tools.ietf.org/html/rfc5024).
SOAP sigue siendo útil hoy en día si no puede asignar su tarea directamente a los recursos, como lo hacen los servicios básicos HTTP/REST, ya que la tarea a realizar 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 de WSDL en combinación con UDDI permite combinar servicios de forma dinámica.
2: https://www.wikiod.com/es/rest/empezando-con-el-descanso#RESTO sobre HTTP
Creando 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.
// Interfaz de servicio con targetNamespace personalizado @WebService(targetNamespace = “http://hello-soap/ws”) @SOAPBinding(estilo = Estilo.DOCUMENTO, uso=Uso.LITERAL) //opcional interfaz pública HelloSoap {
@WebMethod String getHelloSoap(String name);
} </código>
- 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 un conjunto de reglas [28.1.1 Requisitos de un punto final JAX-WS] (https://docs.oracle.com/javaee/7/tutorial/jaxws001.htm#BNAYN) que deben seguir los puntos finales JAX-WS. El método getHelloSoap devuelve un saludo al cliente con el nombre que se le pasa.
// Implementación de servicios personalizados (portName, serviceName, targetNamespace son opcionales)
@WebService(portName = “HelloSoapPort”, serviceName = “HelloSoapService”, endpointInterface = “com.wonderland.hellosoap.HelloSoap”, targetNamespace = “http://hello-soap/ws”) clase pública HelloSoapImpl implementa HelloSoap {
@Override
public String getHelloSoap(String name) {
return "[JAX-WS] Hello : " + name;
}
} </código>
- Editor de punto final de servicio web
public class HelloSoapPublisher {
public static void main(String[] args) {
// creating web service endpoint publisher
Endpoint.publish("http://localhost:9000/ws/hello-soap", new HelloSoapImpl());
}
} </código>
- Siguientes 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 dar el siguiente paso.
Nota: Si recibe algún tipo de mensaje de error, tal vez necesite usar la herramienta
wsgen
para generar los artefactos portátiles JAX-WS necesarios. Nosotros no están cubiertos sobre la herramientawsgen
aquí.
- Cliente de servicio web
Paso final, crearemos un cliente que acceda a nuestro servicio publicado.
importar javax.xml.espacio de nombres.QName; importar javax.xml.ws.Servicio;
clase pública 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 "));
}
} </código>
Producción:
[JAX-WS] Hola: Jabón
Nota: El número de puerto cambió a 8000
en nuestro cliente de servicio web. La razón aquí es que usé Eclipse IDE, la herramienta incorporada TCP/IP monitor
para rastrear mensajes (Más información: [Cómo rastrear mensajes SOAP en Eclipse IDE] (http://www.mkyong.com/webservices/ jax-ws/how-to-trace-soap-message-in-eclipse-ide/)). Para fines de prueba funcional, intente [SoapUI | Pruebas funcionales para SOAP y API REST] (https://www.soapui.org).
Cliente Java para servicio meteorológico servicio web de código abierto 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();
}
}
}