A Web Services Definition Language (WSDL) (em tradução livre: linguagem de definição de Web Services) é um vocabulário XML para criar contratos de serviços.
Cada Web Service é definido por um contrato WSDL.
O contrato WSDL contém toda a informação necessária para criar um cliente capaz de comunicar com o Web Service. Existem várias ferramentas capazes de criar clientes de Web Services de forma automática, sendo o JAX-WS uma delas.
O contrato WSDL indica quais as operações disponibilizadas pelo Web Service aos seus clientes. O conjunto das operações é designado por interface. Para cada operação são especificados os argumentos (inputs), os resultados (outputs) e os erros (faults). Os tipos de dados dos argumentos, resultados e erros são descritos com esquemas XSD.
O contrato WSDL não é fácil de ler, não só porque é extenso, mas também porque a sua organização está invertida e tem múltiplas dependências. A figura seguinte resume a estrutura.
O primeiro aspecto a perceber
é que existe uma separação entre
interface abstracta e
interface concreta.
A interface abstracta (port type) define as operações e mensagens.
A interface concreta (port) faz o vínculo de interface
a um conjunto concreto de tecnologias.
Esta separação permite que um mesmo Web Service
possa ser implementado com tecnologias alternativas.
Na prática, a vinculação (binding)
mais comum é com SOAP e HTTP.
O exemplo seguinte é o contrato WSDL de um Web Service de "Hello World", que tem uma operação "sayHello", que recebe um nome e devolve uma saudação.
01 <?xml version="1.0" encoding="UTF-8"?> 02 03 <definitions name="Hello" 04 targetNamespace="http://hello" 05 xmlns:tns="http://hello" 06 xmlns="http://schemas.xmlsoap.org/wsdl/" 07 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 08 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> 09 <types> 10 <xsd:schema elementFormDefault="qualified" 11 targetNamespace="http://hello"> 12 13 <xsd:complexType name="sayHelloType"> 14 <xsd:sequence> 15 <xsd:element name="name" type="xsd:string" /> 16 </xsd:sequence> 17 </xsd:complexType> 18 <xsd:element name="sayHello" type="tns:sayHelloType" /> 19 20 <xsd:complexType name="sayHelloResponseType"> 21 <xsd:sequence> 22 <xsd:element name="return" type="xsd:string" /> 23 </xsd:sequence> 24 </xsd:complexType> 25 <xsd:element name="sayHelloResponse" type="tns:sayHelloResponseType" /> 26 27 </xsd:schema> 28 </types> 29 30 <message name="sayHello"> 31 <part name="parameters" element="tns:sayHello" /> 32 </message> 33 <message name="sayHelloResponse"> 34 <part name="result" element="tns:sayHelloResponse" /> 35 </message> 36 37 <portType name="HelloPortType"> 38 <operation name="sayHello"> 39 <input message="tns:sayHello" name="sayHello"/> 40 <output message="tns:sayHelloResponse" name="sayHelloResponse"/> 41 </operation> 42 </portType> 43 44 <binding name="HelloBinding" type="tns:HelloPortType"> 45 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 46 <operation name="sayHello"> 47 <soap:operation soapAction="" /> 48 <input> 49 <soap:body use="literal" /> 50 </input> 51 <output> 52 <soap:body use="literal" /> 53 </output> 54 </operation> 55 </binding> 56 57 <service name="HelloService"> 58 <port name="HelloPort" binding="tns:HelloBinding"> 59 <soap:address location="http://server:port/context/endpoint" /> 60 </port> 61 </service> 62 63 </definitions>
O 'service' define um 'port' (linhas 57-61 do exemplo)
que é uma interface concreta de
acesso ao serviço. O endereço de acesso é indicado na linha 59.
O 'port' concretiza a interface abstracta do 'port type' (linhas 37-42),
através do 'binding' (44-55).
O 'port type' define a 'operation' "sayHello" (38-41),
que tem como 'input' e 'output', respectivamente
as 'message': "tns:sayHelloRequest" (30-32) e "tns:sayHelloResponse" (33-35).
Cada 'message' tem pelo menos uma 'part'.
Cada 'part' é definida por um tipo ou elemento XSD.
Neste caso são usados os elementos "sayHello" (18) e
"sayHelloResponse" (25).
Os tipos são os 'complexTypes'
"sayHelloType" (13-17) e "sayHelloResponseType" (20-24).
Os espaços de nomes (3-8, 11) desempenham aqui um papel importante,
pois permitem saber onde são definidos
os vários elementos XML que são necessário no WSDL.
A vinculação (binding) do Web Service especifica que o serviço usa mensagens SOAP e que as mensagens devem ser transportadas usando o protocolo HTTP.
Exemplo de pedido SOAP transportado por HTTP:
POST /ExemploHelloWS/endpoint HTTP/1.1 Host: www.server.com Content-Type: text/xml; charset="utf-8" Content-Length: 322 SOAPAction: "" <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://hello"> <soapenv:Body> <ns1:sayHello> <ns1:name>friend</ns1:name> </ns1:sayHello> </soapenv:Body> </soapenv:Envelope>
Exemplo de resposta SOAP transportada por HTTP:
HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: 367 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://hello"> <soapenv:Body> <ns1:sayHelloResponse> <ns1:return>Hello friend!</ns1:return> </ns1:sayHelloResponse> </soapenv:Body> </soapenv:Envelope>
Existem variantes do SOAP binding, cujas diferenças
são a forma como os dados são transportados
no 'body'.
Se forem transportados em múltiplas 'part' dentro
das 'message', especificadas por tipos XSD,
então temos a variante 'RPC Literal'.
Se forem transportados numa única 'part' da 'message',
especificadas por elementos XSD,
então temos a variante 'Document Literal'.
Existe ainda uma terceira variante,
designada por 'RPC encoded',
onde os dados não são definidos por XSD,
que está a ser progressivamente abandonada.
© Docentes de Sistemas Distribuídos,
Dep. Eng. Informática,
Técnico Lisboa