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.

ingrese la descripción de la imagen aquí([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 oxs: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.

Directorio de proyectos

  1. 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.

importar javax.jws.WebMethod; importar javax.jws.WebService; importar javax.jws.soap.SOAPBinding; importar javax.jws.soap.SOAPBinding.Style; importar javax.jws.soap.SOAPBinding.Use;

// 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>

  1. 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.

importar javax.jws.WebService;

// 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>

  1. Editor de punto final de servicio web
importar 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());
}

} </código>

  1. Siguientes pasos, ejecutaremos HelloSoapPublisher.java como aplicación java. Luego, veremos el archivo WSDL solicitando la URL http://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.

hola-soap?wsdl

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 herramienta wsgen aquí.

  1. Cliente de servicio web

Paso final, crearemos un cliente que acceda a nuestro servicio publicado.

importar java.net.URL;

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();
    }
}

}