Вы находитесь на странице: 1из 25

3. WSDL. EL LENGUAJE DE DEFINICIN DE SERVICIOS WEB 3.1. Introduccin 3.2. Objetivos 3.3.

Historia del Lenguaje de Descripcin de Servicios Web 3.4. Por qu WSDL? 3.5. La sintaxis de WSDL 3.6. Primitivas de transmisin 3.7. Enlace a protocolos 3.8. Ejercicio Resuelt 3.9. Cuestionario de autoevaluacin 3.10. Conclusiones

3.1. Introduccin
A lo largo del presente curso se introducirn los conceptos principales relacionados con los Servicios Web, principales exponentes de un nuevo paradigma para la creacin de aplicaciones distribuidas. Los Servicios Web son aplicaciones modulares autodescriptivas, las cuales pueden ser publicadas, localizadas, e invocadas desde cualquier parte de Internet. El elemento clave que se puede encontrar detrs de los Servicios Web es el XML (Extensible Markup Language), utilizado como ncleo de la mayora de las tecnologas existentes para los Servicios Web. Es por ello que normalmente se conoce a los Servicios Web como Servicios Web XML. Gracias a la aparicin de los Servicios Web nos encontramos ante un nuevo modelo de programacin. Se ha desarrollado un nuevo conjunto de estndares que nos da acceso programtico a la lgica de aplicacin de la Web. Esta lgica es accesible para todo tipo de clientes, independientemente de la plataforma que tengan por debajo y del lenguaje de programacin en el que hayan sido programados. Por medio de este modelo, se pueden desarrollar aplicaciones que integren distintos componentes utilizando protocolos estndar de Internet. De entre estos estndares, se estudiaran en el curso sobre todo SOAP y WSDL, que son las piezas fundamentales de los Servicios Web. SOAP proporciona un mecanismo estndar para el transporte de mensajes para su uso por Servicios Web, mientras que WSDL busca definir y describir los Servicios Web de la misma forma que los archivos de cabecera o las libreras de tipos definen y describen las libreras binarias de toda la vida en los lenguajes de programacin clsicos. Una vez comprendida la teora que hay detrs de los servicios Web, los captulos finales del curso ensearan a desarrollar estos servicios utilizando tecnologas Java, entre las que destacan ciertos frameworks de desarrollo que nos facilitarn la tarea, como JAX-WS, o la librera Axis2. Adems, se profundizar en el desarrollo de clientes para acceder a estos Servicios Web.

3.2. Objetivos
Los objetivos del presente captulo son los siguientes: Conocer una breve historia del WSDL

Comprender el porqu del WSDL Conocer la sintaxis del WSDL Conocer todos los elementos del WSDL.

3.3. Historia del Lenguaje de Descripcin de Servicios Web


Las dos empresas que dieron los primeros pasos para la creacin del WDSL, como ya se ha indicado en la introduccin, fueron Microsoft e IBM, empresas ambas detrs del desarrollo de la especificacin 1.1 de SOAP. El motivo que mova a ambas empresas era el de desarrollar unos toolkits de desarrollo sobre SOAP para solventar el problema del fichero de cabecera (o descubrir programticamente cmo formatear un mensaje SOAP para llamar a un servicio SOAP concreto). La solucin de IBM se llam NASSL (Network Accessibility Service Specification Language), el cual fue lanzado dentro de la primera versin del toolkit SOAP for Java. NASSL utilizaba XML para describir tanto interfaces para el Servicio Web como para asociarlo con determinadas URLs. Tambin utilizaba Esquemas XML (XSD) para describir los tipos de datos utilizados en los servicios. Ms o menos al mismo tiempo (ao 2000), Microsoft lanz SCL (Service Contract Language), junto con su primera versin del SOAP Toolkit for Visual Studio. SCL tambin utilizaba XML como medio para describir los Servicios Web, pero utilizaban el formato XML Data-Reduced (XDR) para la definicin de tipos. Al poco tiempo Microsoft actualiz el SCL a SDL (Services Description Language), lanzado con la primera versin del Visual Studio .NET. Sin embargo, en este punto surgi un nuevo problema. Los Servicios Web surgan como solucin para permitir la comunicacin entre plataformas. Sin embargo, las dos implementaciones de SOAP principales eran incompatibles entre s. La solucin a este problema fue WDSL. Microsoft e IBM trabajaron de forma conjunta con Ariba, y desarrollaron la primera versin de WSDL, la cual incorporaba ideas de los trabajos previos en la descripcin de servicios. Tambin se decidi que WSDL utilizase estndares abiertos, por lo que utiliz XSD para describir sus tipos de datos, y otros estndares como SOAP y MIME para describir sus bindings especficos. WSDL 1.1 fue publicado en el W3C como una Nota en marzo de 2001.

3.4. Por qu WSDL?


Para satisfacer esa visin de los Servicios Web de millones de piezas o componentes independientes, todos disponibles a travs de Internet, y accesibles desde cualquier plataforma y a travs de cualquier lenguaje de programacin, los Servicios Web deben de ser autodescriptivos. Si todos los Servicios Web publicasen sus interfaces mediante WSDL, sera posible para cualquier cliente de esos servicios llamarlos de forma programtica sin tener que conocer nada acerca de los detalles de implementacin de cada servicio, o acerca de sobre qu plataforma o sistema operativo estn corriendo los mismos. WSDL est construido sobre estndares como XML, XSD, SOAP y MIME en un esfuerzo de hacerlo independiente de plataforma, implementacin y dispositivo.

3.5. La sintaxis de WSDL


3.5.1 Introduccin
WSDL proporciona una gramtica que describe los servicios como un conjunto de endpoints que intercambian mensajes. Uno de los conceptos principales detrs de las descripciones est en la idea de que existe diferencia entre la definicin abstracta de un mensaje, y la forma concreta en la que esos mensajes se traducen a protocolos de transporte y/o de codificacin de datos. En la prctica, lo normal es que la mayora de los desarrolladores hagan uso de alguna herramienta de ayuda en la creacin de los documentos WSDL antes de codificarlos a mano. Sin embargo, es importante comprender la sintaxis de WSDL antes de empezar a utilizar estas herramientas, ya que en la mayora de los casos, aunque la herramienta genera un buen document o, lo normal es que al final haya que modificar cosas a mano para dejar el WSDL a nuestro gusto. Un documento WSDL est formado por definiciones. Estas definen un servicio como un conjunto de uno o ms endpoints, o puertos (ports). Cada puerto est asociado con un enlace (binding) especfico. Este binding define cmo un conjunto abstracto de operaciones y mensajes estn enlazados con un puerto por medio de un protocolo especfico. Un enlace (binding) relaciona un protocolo especfico con un port-type. Un port-type est formado por una o ms operaciones (operations). Las operaciones representan un conjunto abstracto de cosas que el servicio puede hacer. Cada operacin est formada por un conjunto abstracto de mensajes (messages), los cuales representan la informacin transmitida durante la operacin. Cada mensaje contiene una o ms piezas de informacin, las cuales se definen mediante tipos (types). Por tanto, y como se puede imaginar, cada documento WSDL estar formado por los siguientes elementos:
o o o o o

Types. Messages. Operations. Port Types. Bindings. Ports. Services.

Cada definicin abstracta de un tipo, mensaje u operacin puede enlazarse con uno o ms puertos, de modo que el mismo mensaje puede ser enviado a travs de diferentes puertos utilizando diferentes codificaciones. Se han definido tres tipos de enlace en WSDL 1.1.:
o o

SOAP 1.1 HTTP GET/POST MIME

Finalmente, WSDL no est limitado a un nico tipo de esquema para definir los tipos. Se puede utilizar cualquier mecanismo vlido para definir tipos, aunque por defecto se utilizar XSD.

3.5.2 Espacios de nombres La tabla siguiente muestra el conjunto de espacios de nombres utilizados en WDSL, as como el prefijo tpico asociado a cada uno de ellos. Puede ser necesaria la utilizacin de otros espacios de nombres para bindings adicionales, como por ejemplo SMTP, pero esos se dejan a la eleccin del autor del documento, ya que no estn definidos en la Especificacin.

3.5.3 Documentation Existe un elemento especfico llamado wsdl:documentation que alberga documentacin legible por el ojo humano, y que puede ir en el interior de cualquier otro elemento WSDL. El contenido de este elemento puede ser tanto texto como otros elementos XML. Normalmente, este elemento sirve para crear comentarios dentro de un documento WSDL, y debe utilizarse en lugar de las etiquetas de comentario XML (<!-- -->), as las aplicaciones pueden acceder a los elemento documentation y generar documentos con los detalles del WSDL legibles por las personas. 3.5.4 Types El elemento types se utiliza para describir los tipos de estructuras de informacin que sern incluidas en los mensajes. En teora se podra utilizar cualquier lenguaje de esquemas dentro de este elemento para describir el formato del mensaje, pero de acuerdo con la especificacin del W3C, WSDL prefiere XSD. Sin embargo, es importante tener en cuenta que aunque se utilice XSD para describir el esquema de un tipo, la representacin real en la comunicacin de ese tipo puede que no ser XML. Por ejemplo, el siguiente esquema describe un tipo llamado TemperaturaActualRequest el cual tiene dos hijos, codigoCiudad (string) y formatoTemp (un string que o bien es celsius o fahrenheit).

--<definitions...> <types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xsd:element name="TemperaturaActualRequest"> <xsd:complexType> <xsd:sequence> <xsd:element name="codigoCiudad" type="xsd:string"/> <xsd:element name="formatoTemp"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="celsius"/> <xsd:enumeration value="fahrenheit"/> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </types> </definitions> --Si el tipo definido anteriormente fuese parte de un mensaje enlazado a la codificacin SOAP, el formato para enviarlo por la red sera el siguiente: --<GetTemperaturaActualRequest> <codigoCiudad>MAD</codigoCiudad> <formatoTemperatura>celsius</formatoTemperatura> </GetTemperaturaActualRequest> --Sin embargo, si ese mismo mensaje estuviese enlazado con HTTP GET/POST, el formato real sera el siguiente: --POST /TemperaturaActual HTTP/1.1 Host: www.servidordetemperatura.com Content-Type: application/x-www-form-urlencoded Content-Length: ### codigoCiudad=MAD&formatoTemp=celsius --Las estructuras de datos descritas por el elemento types son tipos abstractos. Son representaciones conceptuales del formato de los datos del mensaje, pero no el formato final. El formato final estar determinado por el protocolo utilizado para la comunicacin. Puesto que los tipos son abstractos, existen una serie de recomendaciones acerca de cmo utilizar los esquemas XSD para representarlos:

Utilizar elementos, no atributos. No representar ningn tipo especfico de un protocolo, como por ejemplo soap:encodingStyle. o Los arrays no deben utilizar el formato de codificacin de arrays de SOAP 1.1 o Utilizar xsd:anyType siempre que el tipo no importe. Siguiendo las pautas anteriores, la tarea de traducir esquemas XSD a formatos no basados en XML, como puede ser el binding HTTP GET/POST, se convierte en una tarea relativamente sencilla. 3.5.5 Messages Una vez se ha definido el conjunto de tipos, es el momento de componerlos en mensajes. Cada definicin de un mensaje (y de nuevo estos mensajes son representaciones abstractas del mensaje, no el mensaje real que se enviar por la red) est formada por una o ms partes lgicas, cada una de las cuales estar asociada con un tipo. Es decir, un elemento message contiene elementos part, y cada uno de los elementos part hace referencia a un tipo definido en el elemento types. Puesto que WSDL utiliza XSD como sistema de tipado, la referencia al tipo se puede llevar a cabo de dos maneras:

Utilizando element cuando se enlace con un nico elemento XSD por nombre. Utilizando type cuando se haga referencia a un simpleType o complexType.

Esto se convierte en atributos del elemento part, como se puede ver a continuacin: --<definitions> <message name="nombremensaje"> <part name="nombreparte" element="nombreElementoTipo" | type="nombreTipo"/> </message> </definitions> --Tanto el nombre del mensaje como el de cada una de las partes se deja a eleccin del programador, siempre que sean nicos dentro del mbito del documento. Se debe tener en cuenta que existen dos formas diferentes de traducir partes de mensaje a tipos. Por ejemplo, si se tiene el siguiente esquema: --<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="DireccionEntrega"> <xsd:complexType> <xsd:element name="Calle" type="xsd:string"/> <xsd:element name="Ciudad" type="xsd:string"/> <xsd:element name="Provincia" type="xsd:string"/> <xsd:element name="CodigoPostal" type="xsd:string"/> <xsd:element name="Pais" type="xsd:string"/> </xsd:complexType> </xsd:element> <xsd:element name="DireccionFacturacion"> <xsd:complexType> <xsd:element name="Calle" type="xsd:string"/>

<xsd:element name="Ciudad" type="xsd:string"/> <xsd:element name="Provincia" type="xsd:string"/> <xsd:element name="CodigoPostal" type="xsd:string"/> <xsd:element name="Pais" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:schema> --Los elementos part estn pensados para funcionar como una separacin lgica de la informacin dentro de un nico mensaje. Si quisisemos separar la nocin de Direccin de Entrega de Direccin de Facturacin a travs de elementos part, habra que hacer algo as: --<definitions...> <message name="SetDireccionCliente"> <part name="DireccionEntrega" element="DireccionEntrega"/> <part name="DireccionFacturacion" element="DireccionFacturacion"/> </message> </definitions> --Sin embargo, la estructura del mensaje puede llegar a ser tan compleja que suele resultar ms sencillo gestionar esta complejidad desde el XSD en vez de separar el mensaje en partes. Por ejemplo, esto podra resolverse de la siguiente manera: --<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="DireccionEntrega"> <xsd:complexType> <xsd:element name="Calle" type="xsd:string"/> <xsd:element name="Ciudad" type="xsd:string"/> <xsd:element name="Provincia" type="xsd:string"/> <xsd:element name="CodigoPostal" type="xsd:string"/> <xsd:element name="Pais" type="xsd:string"/> </xsd:complexType> </xsd:element> <xsd:element name="DireccionFacturacion"> <xsd:complexType> <xsd:element name="Calle" type="xsd:string"/> <xsd:element name="Ciudad" type="xsd:string"/> <xsd:element name="Provincia" type="xsd:string"/> <xsd:element name="CodigoPostal" type="xsd:string"/> <xsd:element name="Pais" type="xsd:string"/> </xsd:complexType> </xsd:element> <xsd:complexType name="DireccionCliente"> <xsd:sequence> <xsd:element ref="DireccionEntrega"/> <xsd:element ref="DireccionFacturacion">

</xsd:sequence> </xsd:complexType> </xsd:schema> --Por lo que la definicin del mensaje quedara de la siguiente manera: --<definitions...> <message name="SetDireccionCliente"> <part name="Direccion" type="DireccionCliente"/> </message> </definitions> --Ambos mtodos son igualmente vlidos, y depender del programador elegir cual utilizar. 3.5.6 Port Type Un port-type es un conjunto de mensajes agrupados en operaciones. Cada una de estas operaciones representa una unidad nica de trabajo para el servicio que se est describiendo. Los tipos de operaciones, conocidos como primitivas de transmisin (transmission primitives) se vern tras el estudio de los diferentes elementos de WSDL. Los portType puede estar formados por ms de una operacin, siendo su estructura la siguiente: --<definitions> <portType name="nombre"> <operation name="nombreOperacion"> <input name="nombre" message="nombreCalificadoMensaje"/> <output name="nombre" message="nombreCalificadoMensaje"/> <fault name="nombre" message="nombreCalificadoMensaje"/> </operation> </portType> </definitions> --Cada operacin puede estar compuesta por mensajes de entrada (input), de salida (output) o de error (fault). Los mensajes que aparezcan dependern de la primitiva de transmisin que se est utilizando en un momento dado. Se puede pensar en las operaciones como si de mtodos se tratase, ya que estos ltimos tienen normalmente parmetros de entrada, parmetros de salida, y potencialmente tienen errores. Las operaciones pueden recibir informacin mediante input, devolver resultados mediante output, y notificar excepciones mediante fault. (Fault contendr informacin especfica de la aplicacin, diferente a cualquier protocolo especfico de informacin de errores, como por ejemplo soap:fault. El ejemplo siguiente muestra cmo definir una operacin como parte de un port-type. --<definitions>

<message name="GetHoraActualInput"> <part name="body" element="xsd1:HoraActualRequest"/> </message> <message name="GetHoraActualOutput"> <part name="body" element="xsd1:HoraActual"/> </message> <portType name="HoraActualPortType"> <operation name="GetHoraActual"> <input message="tns:GetHoraActualInput"/> <output message="tns:GetHoraActualOutput"/> </operation> </portType> </definitions> --A la operacin se le enva un mensaje del tipo GetHoraActualInput, la cual responde con un mensaje GetHoraActualOutput. La operacin est pensada para ser abstracta, y por tanto no incluye ningn detalle de cmo enlazarla con algn protocolo especfico. En la prctica, cuando se realiza el enlace de la operacin con algn protocolo, la operacin anterior se puede convertir en una peticin/respuesta, o en dos mensajes separados e independientes. El cmo se traduce una operacin a un protocolo determinado se define con los bindings. 3.5.7 Bindings Como ya se coment anteriormente, un binding (o enlace) define cmo asociar o enlazar una operacin concreta con un protocolo especfico. Cada operacin se traduce al protocolo indicado mediante una sintaxis especfica de dicho protocolo. Existen tres bindings especificados por WSDL, los cuales se estudiarn en la seccin Enlace a protocolos. La sintaxis de un binding es muy parecida a la de un port-type, pero en este caso cada operacin se traduce a una operacin especfica del protocolo. El cdigo siguiente muestra cmo un elemento binding contiene operaciones, as como dnde encaja la informacin de traduccin especfica del protocolo. --<definitions...> <binding name="nombre" type="nombreCalificado"> <!-- La informacin de traduccin especfica del Binding ira aqu --> <operation name="nombre"> <!-- La informacin de traduccin especfica ira aqu --> <input name="nombre"> <!-- La informacin de traduccin especfica de la entrada ira aqu --> </input> <output name="nombre"> <!-- La informacin de traduccin especfica de la salida ira aqu --> </output>

<fault name="nombre"> <!-- La informacin de traduccin especfica del error ira aqu --> </fault> </operation> </binding> </definitions> --Puesto que una operacin puede enlazarse a ms de un protocolo, y que son muchos los puertos WSDL que pueden utilizar cada binding, cada enlace debe especificar solamente un protocolo, y no pueden especificar una direccin. Esto se entender mejor con el siguiente ejemplo: --<definitions> <binding name="GetHoraActualSOAP" type="GetHoraActualPortType"> <!-- La informacin de traduccin especfica del Binding ira aqu --> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetHoraActual"> <!-- La informacin de traduccin especfica ira aqu --> <soap:operation soapAction="http://www.ejemplo.com/GetHoraActual"/> 3.5.8 Ports y Services Un puerto (port) asocia un binding con una direccin especfica de un protocolo. Esto representa los nodos o endpoints de red reales, con los cuales el servicio se comunica. Un servicio (service) representa una coleccin de puertos en forma de unidad lgica. El cdigo siguiente representa la relacin entre un puerto y un servicio. --<definitions...> <service name="nombre"> <port name="nombre" binding="nombreCalificado"> <!-- La informacin de la direccin especfica del protocolo va aqu --> </port> </service> </definitions> --Cada puerto especifica un binding, el cual hace referencia a un elemento binding definido anteriormente, y a una y slo una direccin. La forma en la que se especifica esta direccin es especfica del protocolo. Por ejemplo: --<definitions...> <service...> <port name="HoraActualPort" binding="GetHoraActualSOAP"> <!-- La informacin de la direccin especfica del protocolo va aqu --> <soap:address location="http://www.ejemplo.com/hora" /> </port>

</service> </definitions> --Un nico servicio puede tener varios puertos que utilicen el mismo portType, pero tendrn diferentes bindings y/o direcciones. En este caso, estos puertos ofrecen alternativas al usuario a la hora de elegir el protocolo que desee usar para comunicarse con el servicio, o la posibilidad de elegir la direccin que se encuentre ms cercana.

3.6. Primitivas de transmisin


3.6.1 Introduccin WSDL define cuatro tipos bsicos de operaciones, llamadas primitivas de transmisin. Estos estilos de operaciones representan los patrones de utilizacin ms normales en Servicios Web, y surgen de las posibles combinaciones de los subelementos input y output dentro de un elemento operation de WSDL. Las primitivas son las siguientes: Una direccin Peticin/Respuesta o Solicitud/Respuesta o Notificacin Una curiosidad relativa a los cuatro tipos de operacin anteriores es que aunque todos ellos estn descritos en la Especificacin WSDL 1.1, solamente han sido incluidos los bindings para las operaciones de una direccin y de peticin/respuesta. Se espera que se publiquen los bindings a SOAP o a HTTP GET/POST correspondientes a solicitud/respuesta y a notificacin, en versiones actualizadas de la especificacin. 3.6.2 Operacin en un direccin (One-way) Una operacin de una sola direccin es aquella en la que el endpoint recibe un mensaje, pero no enva respuesta alguna. Un ejemplo de este tipo de operaciones sera una operacin que represente el envo de una orden de compra a un sistema. Una vez se ha enviado dicha orden, no se espera ninguna respuesta inmediata. En este tipo de operaciones se define un mensaje de entrada, pero no los hay ni de salida ni de error, por lo que no se podra saber si ha ocurrido algn tipo de error en la transmisin. Un ejemplo de mensaje de una direccin sera el siguiente:
--<definitions> <portType name="EnviarOrdenPortType"> <operation name="EnviarOrden"> <input message="EnviarOrdenInput"/> </operation> </portType> </definitions> ---

3.6.3 Operacin Peticin/Respuesta (Request/Response) Una operacin de peticin/respuesta es aquella en la que el endpoint recibe un mensaje y devuelve otro como respuesta al primero. Un ejemplo de este tipo de operacin sera aquella en la que se enva, por ejemplo, el cdigo de una ciudad, y se devuelve la temperatura que hay en dicha ciudad en ese momento dado. Como en este tipo de operaciones s que se espera devolver un valor, se puede devolver un elemento fault en caso de encontrarse un error. Una operacin de peticin/respuesta se definira as: --<definitions...> <portType...> <operation name="nombreOperacion"> <input name="nombre" message="nombreCalificadoMensaje"/> <output name="nombre" message="nombreCalificadoMensaje"/> <fault name="nombre" message="nombreCalificadoMensaje"/> </operation> </portType> </definitions> --3.6.4 Operacin de Solicitud/Respuesta (Solicit/Response) Una operacin de solicitud/respuesta es aquella en la que el endpoint del servicio enva un mensaje, y posteriormente recibe una respuesta. Esta operacin se diferencia con la anterior en que es el servicio el que inicia la operacin, en vez de responder a una peticin. Por tanto, esta operacin se define como se muestra a continuacin: --<definitions...> <portType...> <operation name="nombreOperacion"> <output name="nombre" message="nombreCalificadoMensaje"/> <input name="nombre" message="nombreCalificadoMensaje"/> <fault name="nombre" message="nombreCalificadoMensaje"/> </operation> </portType> </definitions> --Esta operacin es abstracta, ya que no existe actualmente un binding definido para la misma. 3.6.5 Operacin de Notificacin (Notification) Finalmente, el ltimo de los tipos de operaciones definidos se corresponde con la operacin de Notificacin. Esta operacin es aquella en la que el endpoint enva un mensaje y no recibe respuesta alguna. Un ejemplo de notificacin sera, por ejemplo, un modelo de eventos en el que el endpoint informara peridicamente del estado del evento. El formato de esta operacin es el siguiente:

--<definitions...> <portType...> <operation name="nombreOperacion"> <output name="nombre" message="nombreCalificadoMensaje"/> </operation> </portType> </definitions> --Por los mismos motivos que en la operacin anterior, esta operacin tambin es abstracta.

3.7. Enlace a protocolos


3.7.1 Introduccin Una vez se ha estudiado la sintaxis bsica para construir un documento WSDL, es el momento de echar un vistazo a los protocolos para los que WSDL 1.1 define enlaces. Estos son:
o

SOAP HTTP GET/POST MIME

3.7.2 Enlace SOAP El binding SOAP 1.1 para WSDL proporciona mecanismos para indicar que SOAP es el protocolo al que enlazar, qu cabecera SOAPAction es la que hay que utilizar, qu otras cabeceras adicionales de SOAP se deben incluir, y a qu direccin se debe enviar el mensaje. A continuacin se explican los principales elementos. El elemento soap:binding El elemento soap:binding se utiliza dentro del elemento binding para indicar que el enlace se realiza con SOAP, as como para indicar el mecanismo de transporte y el estilo de codificacin utilizado por el documento. --<definitions...> <binding...> <soap:binding style="rpc | document" transport="uri"/> <operation...> </operation> </binding> </definitions> --El atributo obligatorio transport indica qu protocolo utilizar para el enlace SOAP, siendo http://schemas.xmlsoap.org/soap/http el nico valor definido en la

especificacin, lo que significa que SOAP estar siempre asociado a HTTP. Se podran utilizar, por supuesto, otras uris que representen otros enlaces a protocolos de transporte, como SMTP, FTP, etc. El atributo opcional style indica qu estilo de mensaje representa la operacin. El valor rpc indica que el mensaje utiliza el estilo de codificacin RPC, por lo que el mensaje representa una llamada a un mtodo y una lista de parmetros. El valor document sirve para sealar que el mensaje se encuentra en modo documento, por lo que el mensaje representa un nico documento. Si no se especifica ningn valor, se asume el valor document por defecto. El elemento soap:operation El elemento soap:operation se utiliza para sealar como enlazar una operacin con el protocolo SOAP. Esto incluye especificar la cabecera SOAPAction a utilizar para el enlace SOAP, y de forma opcional, un estilo de codificacin. --<definitions...> <binding...> <operation...> <soap:operation soapAction="uri" style="rpc | document"/> </operation> </binding> </definitions> --El atributo soapAction especifica la cabecera HTTP SOAPAction que utilizar en el mensaje SOAP. Siempre que se utilice HTTP como transporte, soapAction es obligatorio. Sin embargo, para otros transportes, puede que no sea necesaria, y el elemento soap:operation puede ser omitido. La URI utilizada para soapAction debe coincidir exactamente con el contenido de la cabecera SOAPAction, por lo que no se deben utilizar direcciones relativas. El atributo style es exactamente el mismo que se vio en el elemento soap:binding anterior. El elemento soap:body Este elemento soap:body define qu partes del mensaje sern incluidas y cmo en el body de SOAP. Esta zona es una en las que el binding se convierte en complicado, puesto que es necesario combinar varios elementos para determinar el objetivo final. El atributo parts es opcional, e indica qu partes (parts) deberan ser incluidas en el body de SOAP. No tiene porqu ser necesario incluir todos los parts del mensaje en el body, pero si se omite el atributo parts, se asume que se incluyen todas las partes del mensaje. Los atributos use, namespace y encodingStyle, combinados con el atributo style de operacin, determinan cmo se traducen las partes al body SOAP. Cada parte puede representar o un mensaje abstracto, en cuyo caso ser funcin de encodingStyle el establecer cmo se traduce esa parte al body SOAP, o un mensaje concreto, en cuyo caso el esquema asociado con dicha parte se utiliza como conjunto de reglas mediante las cuales crear el mensaje. Si el atributo use tiene el valor de literal, entonces esa parte representa un formato concreto. Si en cambio tiene el valor de encoded, ser de nuevo el valor de encodingStyle el que se utilice para determinar

cmo traducir el mensaje abstracto al body SOAP. Adicionalmente, si el estilo de la operacin es rpc, entonces las partes del mensaje son envueltas con un elemento dotado del mismo nombre que la operacin, correspondindose cada parte con un parmetro. Si por el contrario, style tiene el valor document, no se aade ningn envoltorio, y por tanto el body SOAP contendr directamente las partes. Esto se entender mejor viendo el siguiente ejemplo: --<definitions name="TemperaturaActual" targetNamespace="http://www.ejemplo.com/temp.wsdl" xmlns:tns="http://www.ejemplo.com/temp.wsdl" xmlns:xsd1="http://www.ejemplo.com/temp.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <message name="GetTemperaturaActualInput"> <part name="codigoCiudad" element="xsd:string"/> </message> <message name="GetTemperaturaActualOutput"> <part name="tempActual" element="xsd:float"/> </message> <portType name="TemperaturaActualPortType"> <operation name="GetTemperaturaActual"> <input message="tns:GetTemperaturaActualInput"/> <output message="tns:GetTemperaturaActualOutput"/> </operation> </portType> <binding name="TemperaturaActualSoapBinding" type="tns:TemperaturaActualPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTemperaturaActual"> <soap:operation soapAction="http://www.ejemplo.com/GetTemperaturaActual"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> </definitions> --Dado que el estilo de la operacin es document, y que el valor de use es literal, el mensaje SOAP resultante para el mensaje de entrada de la operacin GetTemperaturaActual sera:

--POST /TemperaturaActual HTTP/1.1 Host: www.eltiempo.com Content-Type: text/xml; charset=utf-8 Content-Length: ### SOAPAction: http://www.ejemplo.com/GetTemperaturaActual <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <codigoCiudad>MAD</codigoCiudad> </soapenv:Body> </soapenv:Envelope> --Sin embargo, si ahora cambisemos el estilo del documento a rpc: --... <binding name="TemperaturaActualSoapBinding" type="tns:TemperaturaActualPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTemperaturaActual"> <soap:operation soapAction="http://www.ejemplo.com/GetTemperaturaActual"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> </operation> </binding> ... --Entonces se aade un envoltorio (GetTemperaturaActual) en el body SOAP tal y como puede verse a continuacin: --POST /TemperaturaActual HTTP/1.1 Host: www.eltiempo.com Content-Type: text/xml; charset=utf-8 Content-Length: ### SOAPAction: http://www.ejemplo.com/GetTemperaturaActual <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <GetTemperaturaActual> <codigoCiudad>MAD</codigoCiudad> </GetTemperaturaActual> </soapenv:Body> </soapenv:Envelope> ---

Si ahora se cambiase el valor de use a encoded, y se establece el valor de encodingStyle a la codificacin de SOAP 1.1: --... <binding name="TemperaturaActualSoapBinding" type="tns:TemperaturaActualPortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTemperaturaActual"> <soap:operation soapAction="http://www.ejemplo.com/GetTemperaturaActual"/> <input> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding" namespace="http://www.ejemplo.com/temp" /> </input> <output> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding" namespace="http://www.ejemplo.com/temp" /> </output> </operation> </binding> ... --Se obtendra la siguiente peticin SOAP: --POST /TemperaturaActual HTTP/1.1 Host: www.eltiempo.com Content-Type: text/xml; charset=utf-8 Content-Length: ### SOAPAction: http://www.ejemplo.com/GetTemperaturaActual <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <m:GetTemperaturaActual xmlns:m="http://www.ejemplo.com/temp"> <m:codigoCiudad>MAD</m:codigoCiudad> </m:GetTemperaturaActual> </soapenv:Body> </soapenv:Envelope> --El elemento soap:fault El elemento soap:fault sirve para generar informacin de errores. --<definitions...> <binding...> <operation...> <fault...> <soap:fault name="nombre" use="encoded | literal" namespace="uri" encodingStyle="uri"/>

</fault> </operation> </binding> </definitions> --El atributo name traduce el elemento soap:fault al elemento wsdl:fault. Los otros atributos (use, namespace, y encodingStyle) tienen la misma funcin que en soap:body. La nica diferencia es que los mensajes de error solamente pueden tener una parte, por lo que el atributo parts aqu no se utiliza, y adems, se asume style=document, puesto que los faults no tienen parmetros. Los elementos soap:header y soap:headerfault Estos dos elementos, soap:header y soap:headerfault se corresponden prcticamente con soap:body y con soap:fault. Simplemente existen unas pequeas diferencias en cmo las partes se asocian con estos elementos de cabecera, por lo que no merece la pena profundizar ms en ellos. 3.7.3 Enlace HTTP GET/POST El enlace HTTP GET/POST define tres maneras distintas de asociar un mensaje con una direccin HTTP, que son:
o

HTTP GET con codificacin de URL HTTP GET con sustitucin de URL HTTP POST

Estos mtodos permitirn que se pueda acceder a un servicio utilizando un simple navegador de Internet, con lo que potencialmente se le est permitiendo el acceso al servicio a todo tipo de dispositivos, no slo ordenadores, que sean capaces de soportar HTTP. Tmese como ejemplo un servicio que recibe dos nmeros y devuelve como texto la suma de ambos. El port-type sera parecido al siguiente: --<definitions...> <message name="SumaInput"> <part name="op1" element="xsd:int"/> <part name="op2" element="xsd:int"/> </message> <message name="SumaOutput"> <part name="resultado" element="xsd:string"/> </message> <portType name="SumaPortType"> <operation name="Suma"> <input message="SumaInput"/> <output message="SumaOutput"/> </operation> </portType> </definitions> ---

Las tres formas en las que se podra realizar el enlace de este port-type son las siguientes. La primera sera HTTP POST: --<binding name="bPost" type="SumaPortType"> <http:binding verb="POST"/> <operation name="Suma"> <http:operation location="loc1"/> <input> <mime:content type="aplication/x-www-form-urlencoded"/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> --Esto resultar en un binding HTTP POST con la direccin http://www.ejemplo.com/loc1, donde el cuerpo del POST ser, por ejemplo, op1=3&op2=2. La direccin http://www.ejemplo.com viene del elemento port que se mostrar en el ltimo bloque de cdigo. Para utilizar HTTP GET se tienen dos opciones. La primera es utilizar el elemento http:urlEncoded, de modo que las partes del mensaje se utilicen como parmetros en la peticin GET: --... <binding name="bGet1" type="SumaPortType"> <http:binding verb="GET"/> <operation name="Suma"> <http:operation location="loc1"/> <input> <http:urlEncoded/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> ... --De este modo, se realizar un mapping a la direccin HTTP utilizando las partes del mensaje como parmetros de consulta: http://www.ejemplo.com/loc1?op1=3&op2=2 por ejemplo. Finalmente, la otra forma de utilizar GET es mediante la sustitucin de caracteres en la URI, que se corresponde con los nombres de las partes de los mensajes. Se utiliza el elemento http:urlReplacement. --... <binding name="bGet2" type="SumaPortType"> <http:binding verb="GET"/> <operation name="Suma">

<http:operation location="loc1/(op1)/(op2)"/> <input> <http:urlReplacement/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> ... --El cdigo anterior enlazara con una URL sin parmetros de consulta, pero con ciertos caracteres en las posiciones de reemplazo. Es decir, los nombre de las partes del mensaje en parntesis sern reemplazadas con los valores del parmetro, resultando una llamada a http://www.ejemplo.com/loc1/3/2. Por supuesto, sera posible utilizar los tres tipos de codificacin dentro de un mismo servicio, permitiendo a los clientes acceder al mismo de la manera que prefieran. --... <service name="SumaService"> <port name="p1" binding="tns:bPost"> <http:address location="http://www.ejemplo.com"/> </port> <port name="p2" binding="tns:bGet1"> <http:address location="http://www.ejemplo.com"/> </port> <port name="p3" binding="tns:bGet2"> <http:address location="http://www.ejemplo.com"/> </port> </service> ... --3.7.2 Enlace MIME El ltimo de los tres bindings definidos por WSDL es el binding MIME. WSDL tambin permite enlazar partes de un mensaje a tipos de datos utilizando tipos MIME. Se definen enlaces explcitos con los tipos mutipart/related y text/xml. Todos los dems tipos MIME pueden representarse utilizando el elemento mime:content. Los enlaces MIME pueden utilizarse en las secciones input o output de un elemento binding, tal y como puede verse a continuacin (y como se pudo observar en los ejemplos del apartado anterior). --... <binding...> <operation...> <input> <!-- Los elementos MIME van aqui --> </input> <output> <!-- Los elementos MIME van aqui -->

</output> </operation> </binding> ... --El elemento mime:multipartRelated se utiliza para asociar diferentes partes de un mensaje a diferentes tipos MIME. El elemento mime:content se utiliza para representar un tipo MIME arbitrario. Posee un atributo opcional part que relaciona el contenido con una parte del mensaje, mientras que el atributo type especifica el tipo MIME utilizado. Los tipos que se utilizan normalmente son text/html, image/gif, y application/x-www-form-urlencoded (que es el tipo utilizado por los formularios HTML).

3.8. Ejercicio Resuelto


El ejercicio resuelto a continuacin pretender mostrar la descripcin completa de un servicio dedicado a mostrar la temperatura actual de una ciudad concreta, as como el pronstico para los prximos das. La peticin de la temperatura podr enviarse mediante una peticin SOAP (cuya respuesta ser o en XML directamente o codificada en varias partes), o va HTTP utilizando cualquiera de las tres posibilidades existentes.

3.9. Cuestionario de autoevaluacin


El documento WSDL comienza con la cabecera XML.
--<?xml version="1.0"?> ---

Lo primero que es necesario declarar son todos los espacios de nombres que se van a necesitar.
--<definitions name="TemperaturaActual" targetNamespace="http://www.ejemplo.com/temp.wsdl" xmlns:tns="http://www.ejemplo.com/temp.wsdl" xmlns:xsd1="http://www.ejemplo.com/temp.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"> ---

A continuacin se define el tipo de la peticin. En este caso se utiliza XSD para definir un tipo codigoCiudad de tipo string, temp de tipo float y pronostico de tipo string.
--<types> <schema targetNamespace="http://www.ejemplo.com/temp.xsd" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="TemperaturaActualRequest"> <complexType> <all> <element name="codigoCiudad" type="string"/>

</all> </complexType> </element> <element name="temp" type="float"/> <element name="pronostico" type="string"/> </schema> </types> ---

En este punto se definen los mensajes. El primero es el mensaje de entrada, el cual utiliza el tipo TemperaturaActualRequest definido anteriormente.
--<message name="GetTemperaturaActualInput"> <part name="body" element="xsd1:TemperaturaActualRequest"/> </message> ---

El segundo es el mensaje de salida, el cual est formado por dos partes (Temperatura y Pronostico) las cuales referencian al tipo apropiado de los definidos anteriormente.
--<message name="GetTemperaturaActualOutput"> <part name="Temperatura" element="xsd1:temp"/> <part name="Pronostico" element="xsd1:pronostico"/> </message> ---

Ahora se define un port-type, el cual recibe un codigoCiudad y devuelve tanto la temperatura como el pronstico del tiempo.
--<portType name="TemperaturaActualPortType"> <operation name="GetTemperaturaActual"> <input message="tns:GetTemperaturaActualInput"/> <output message="tns:GetTemperaturaActualOutput"/> </operation> </portType> ---

A continuacin es el momento de definir los cinco tipos de bindings que se van a utilizar. El primero de ellos utiliza SOAP sobre HTTP. El mensaje de entrada usa codificacin literal, lo que significa que el body SOAP contendr un elemento codigoCiudad, sin envoltorio alguno. El valor devuelto tambin utiliza literal, por lo que el body SOAP contendr dos elementos, temp y pronostico.
--<binding name="TemperaturaActualSoapBinding" type="tns:TemperaturaActualPortType"> <documentation>Un binding a SOAP sobre HTTP</documentation> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTemperaturaActual"> <soap:operation soapAction="http://www.ejemplo.com/GetTemperaturaActual"/> <input> <soap:body use="literal"/>

</input> <output> <soap:body use="literal"/> </output> </operation> </binding> ---

El segundo binding tambin utiliza SOAP, pero con una codificacin distinta para el valor de retorno. En este caso, se utiliza una codificacin MIME multipart, donde la temperatura se devuelve como un elemento XML (temp) y el pronstico como un documento HTML.
--<binding name="TemperaturaActualMIMEBinding" type="tns:TemperaturaActualPortType"> <documentation> Un binding a SOAP sobre HTTP usando tipos MIME </documentation> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="GetTemperaturaActual"> <soap:operation soapAction="http://www.ejemplo.com/GetTemperaturaActual"/> <input> <soap:body use="literal"/> </input> <output> <mime:multipartRelated> <mime:part> <soap:body parts="temp" use="literal"/> </mime:part> <mime:part> <mime:content part="pronostico" type="text/html"/> </mime:part> </mime:multipartRelated> </output> </operation> </binding> ---

El tercer binding utiliza HTTP GET con sustitucin de la URL. Puesto que la direccin que se especifica es pronostico/(codigoCiudad), la parte entre parntesis se reemplazar con el valor de codigoCiudad, por lo que si se consulta la temperatura de Madrid (MAD), la URL sera http://www.ejemplo.com/pronostico/MAD. La respuesta se mostrar como un documento HTML.
--<binding name="TemperaturaActualUrlReplacementBinding" type="tns:TemperaturaActualPortType"> <documentation>Un urlReplacement</documentation> <http:binding verb="GET"/> binding HTTP GET usando

<operation name="GetTemperaturaActual">

<http:operation location="pronostico/(codigoCiudad)"/> <input> <http:urlReplacement/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> ---

El cuarto binding es muy parecido al anterior, con la salvedad que ahora se utiliza GET con URL encoding. Esto significa que la peticin de la temperatura de Madrid generar una URL del estilo http://www.ejemplo.com/pronostico?codigoCiudad=MAD.
--<binding name="TemperaturaActualUrlEncodingBinding" type="tns:TemperaturaActualPortType"> <documentation>Un urlEncoded</documentation> <http:binding verb="GET"/> binding HTTP GET usando

<operation name="GetTemperaturaActual"> <http:operation location="pronostico"/> <input> <http:urlEncoded/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> ---

El quinto y ltimo de los bindings es del tipo HTTP POST, por lo que la peticin se codificar en el cuerpo del HTTP POST como codigoCiudad=MAD.
--<binding name="TemperaturaActualPOSTBinding" type="tns:TemperaturaActualPortType"> <documentation>Un binding HTTP POST</documentation> <http:binding verb="POST"/> <operation name="GetTemperaturaActual"> <http:operation location="pronostico"/> <input> <mime:content type="aplication/x-www-formurlencoded"/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> ---

Finalmente, lo ltimo es definir el servicio. Para ello se enlaza cada binding con un puerto diferente del mismo servicio. Puesto que todos ellos son parte del mismo servicio, WSDL los interpreta como alternativas. Por tanto, una aplicacin podr elegir cualquiera de los protocolos y obtener el mismo resultado.
--<service name="TemperaturaActualService"> <port name="TemperaturaActualPort" binding="tns:TemperaturaActualSoapBinding"> <soap:address location="http://www.ejemplo.com/pronostico"/> </port> <port name="TemperaturaActualMIMEPort" binding="tns:TemperaturaActualMIMEBinding"> <soap:address location="http://www.ejemplo.com/mime/pronostico"/> </port> <port name="TemperaturaActualUrlReplacementPort" binding="tns:TemperaturaActualUrlReplacementBinding"> <http:address location="http://www.ejemplo.com"/> </port> <port name="TemperaturaActualUrlEncodingPort" binding="tns:TemperaturaActualUrlEncodingBinding"> <http:address location="http://www.ejemplo.com"/> </port> <port name="TemperaturaActualPOSTPort" binding="tns:TemperaturaActualPOSTBinding"> <http:address location="http://www.ejemplo.com"/> </port> </service> </definitions>

---

3.10. Ejercicio propuesto


Se desea disear la descripcin de un servicio Web que proporcione la funcionalidad de una calculadora. Dicho servicio deber ofrecer al menos los mtodos suma, resta, multiplicacin y divisin de dos nmeros enteros. Se debe desarrollar el documento WSDL completo.

3.11 Conclusiones
En este captulo se ha estudiado el Lenguaje de Descripcin de Servicios Web, lenguaje indispensable para conseguir la proliferacin de los Servicios Web en Internet. El objetivo de este lenguaje es el de ofrecer una descripcin comn de los Servicios, cmo se enlazan con los protocolos de transporte, y cmo son los tipos que utilizan. WSDL, como se ha podido ver, se construye sobre los estndares abiertos de Internet, como XSD, SOAP y MIME.

Вам также может понравиться