programmera.net -> webservice -> normal för utskrift | info@programmera.net |
WSDL 1.1
1. Vad är WSDL?
WSDL (Web Services Description Language) är ett språk som beskriver meddelandesyntax för webbtjänster. Det finns i dagsläget två versioner av WSDL:
WSDL 2.0 innehåller så många förändringar jämfört med WSDL 1.1 att det måste ses som ett helt eget språk. WSDL 2.0 kommer inte att diskuteras på denna sida.
Nedan följer W3Cs beskrivning av WSDL 1.1:
En intressant punkt är att WSDL 1.1 är oberoende av nätverksprotokoll, något som vi ser senare på denna sida. WSDL 1.1 används dock i oftast tillsammans med följande nätverksprotokoll:
2. Element i WSDL
En WSDL-fil har definitions som rotelement. Direkt under toppnivån kan 7 typer av element existera:
Alltså:
Bilden nedan visar hur de olika elementen i en WSDL-fil hänger ihop:
3. Syntax för WSDL
Nedan beskrivs syntaxen för WSDL 1.1 (taget från W3C):
Nu är det dags för ett exempel..
<wsdl:definitions name="nmtoken"? targetNamespace="uri"?>
<import namespace="uri" location="uri"/>*
<wsdl:documentation .... /> ?
<wsdl:types> ?
<wsdl:documentation .... />?
<xsd:schema .... />*
<-- extensibility element --> *
</wsdl:types>
<wsdl:message name="nmtoken"> *
<wsdl:documentation .... />?
<part name="nmtoken" element="qname"? type="qname"?/> *
</wsdl:message>
<wsdl:portType name="nmtoken">*
<wsdl:documentation .... />?
<wsdl:operation name="nmtoken">*
<wsdl:documentation .... /> ?
<wsdl:input name="nmtoken"? message="qname">?
<wsdl:documentation .... /> ?
</wsdl:input>
<wsdl:output name="nmtoken"? message="qname">?
<wsdl:documentation .... /> ?
</wsdl:output>
<wsdl:fault name="nmtoken" message="qname"> *
<wsdl:documentation .... /> ?
</wsdl:fault>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="nmtoken" type="qname">*
<wsdl:documentation .... />?
<-- extensibility element --> *
<wsdl:operation name="nmtoken">*
<wsdl:documentation .... /> ?
<-- extensibility element --> *
<wsdl:input> ?
<wsdl:documentation .... /> ?
<-- extensibility element -->
</wsdl:input>
<wsdl:output> ?
<wsdl:documentation .... /> ?
<-- extensibility element --> *
</wsdl:output>
<wsdl:fault name="nmtoken"> *
<wsdl:documentation .... /> ?
<-- extensibility element --> *
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="nmtoken"> *
<wsdl:documentation .... />?
<wsdl:port name="nmtoken" binding="qname"> *
<wsdl:documentation .... /> ?
<-- extensibility element -->
</wsdl:port>
<-- extensibility element -->
</wsdl:service>
<-- extensibility element --> *
</wsdl:definitions>
4. Ett exempel på WSDL: Calculator
Pe denna sida ska vi titta på WSDL-filen för en applikation av Hello World-karaktär, nämligen Calculator.
Webbtjänsten Calculator implementerar en enkel miniräknare som kan anropas med SOAP över HTTP. Miniräknaren har i detta fall bara har två operationer, multiplikation och division. Nedan visas hur filen Calculator.wsdl ser ut:
I avsnittet Webbtjänster med Java EE kan du se hur Calculator.wsdl används för att bygga en fungerande webbtjänst:
www.programmera.net/jax/Exemplet Calculator ( med Axis ) .
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="Calculator"
targetNamespace="http://www.your_domain.com/axis/services/Calculator.wsdl"
xmlns:tns="http://www.your_domain.com/axis/services/Calculator.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:cal="http://www.your_domain.com/ns/Calculator.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/" >
<!-- Types -->
<types>
<xsd:schema targetNamespace="http://www.your_domain.com/ns/Calculator.xsd" >
<xsd:complexType name="MultiplicationRequestType" >
<xsd:all>
<xsd:element name="multiplicand" type="xsd:int" />
<xsd:element name="multiplier" type="xsd:int" />
</xsd:all>
</xsd:complexType>
<xsd:complexType name="DivisionRequestType" >
<xsd:all>
<xsd:element name="dividend" type="xsd:int" />
<xsd:element name="divisor" type="xsd:int" />
</xsd:all>
</xsd:complexType>
</xsd:schema>
</types>
<!-- Messages -->
<message name="MultiplicationRequest">
<part name="multiplicationRequestPart" type="cal:MultiplicationRequestType"/>
</message>
<message name="MultiplicationResponse">
<part name="multiplicationReturn" type="xsd:int"/>
</message>
<message name="DivisionRequest">
<part name="divisionRequestPart" type="cal:DivisionRequestType"/>
</message>
<message name="DivisionResponse">
<part name="divisionReturn" type="xsd:float"/>
</message>
<message name="DivideZeroException">
<part name="divideZeroError" type="xsd:string"/>
</message>
<!-- Port types -->
<portType name="CalculatorPortType">
<operation name="multiplication" >
<input message="tns:MultiplicationRequest" name="multiplicationRequest"/>
<output message="tns:MultiplicationResponse" name="multiplicationResponse"/>
</operation>
<operation name="division" >
<input message="tns:DivisionRequest" name="divisionRequest"/>
<output message="tns:DivisionResponse" name="divisionResponse"/>
<fault message="tns:DivideZeroException" name="divideZeroException"/>
</operation>
</portType>
<!-- Bindings -->
<binding name="CalculatorSoapBinding" type="tns:CalculatorPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="multiplication">
<soap:operation soapAction="http://www.your_domain.com/axis/services/Calculator/Multiplication"/>
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.your_domain.com/ns/Calculator.xsd" />
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.your_domain.com/ns/Calculator.xsd" />
</output>
</operation>
<operation name="division">
<soap:operation soapAction="http://www.your_domain.com/axis/services/Calculator/Division"/>
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.your_domain.com/ns/Calculator.xsd" />
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.your_domain.com/ns/Calculator.xsd" />
</output>
<fault>
<soap:fault use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.your_domain.com/ns/Calculator.xsd" />
</fault>
</operation>
</binding>
<!-- Services -->
<service name="CalculatorService">
<port binding="tns:CalculatorSoapBinding" name="Calculator">
<soap:address location="http://localhost:8080/axis/services/Calculator"/>
</port>
</service>
</definitions>
5. definitions
definitions är rotelementet för WSDL-trädet. definitions har två valbara attribut:
definitions-elementet innehåller vanligtvis ytterliga XML "namespace" (xmlns:) som vi ser i vårt exempel:
I detta exempel har de ytterligare namnutrymmena följande funktion:
<definitions name="Calculator"
targetNamespace="http://www.your_domain.com/axis/services/Calculator.wsdl"
xmlns:tns="http://www.your_domain.com/axis/services/Calculator.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:cal="http://www.your_domain.com/ns/Calculator.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/" >
...
</definitions>
6. Namnutrymmet xsd
xsd är ett namnutrymme som innehåller färdiga typer, vilka används på följande sätt:
Tabellen nedan visar vilka standardtyper som xsd innehåller som kan använas för att bygga mer komplexa typer:
Datatyper i xsd Beskrivning string Vanlig sträng av tecken. integer Typen integer definieras som en sträng av siffror som kan vara hur lång som helst. long - int - short - byte - decimal - double - float - Boolean - date - dateTime - QName - hexBinary - base64Binary -
7. types
I types-elementet kan du definiera egna XML-typer som du senare kan använda i message-elementen.
I exemplet Calculator.wsdl har vi skapat typer för inparametrarna till våra 2 operationer multiplication och division:
I detta exempel har alla element-taggar type-attribut av kategorin simpleType som hämtas från namnutrymmet xsd (se ovan). För att typerna som definierats ovan ska gå att använda måste targetNamespace mappas mot ett prefix i definitions-elementet. I vårt fall mappas targetNamespace mot prefixet cal (se ovan).
<types>
<xsd:schema targetNamespace="http://www.your_domain.com/ns/Calculator.xsd" >
<xsd:complexType name="MultiplicationRequestType" >
<xsd:all>
<xsd:element name="multiplicand" type="xsd:int" />
<xsd:element name="multiplier" type="xsd:int" />
</xsd:all>
</xsd:complexType>
<xsd:complexType name="DivisionRequestType" >
<xsd:all>
<xsd:element name="dividend" type="xsd:int" />
<xsd:element name="divisor" type="xsd:int" />
</xsd:all>
</xsd:complexType>
</xsd:schema>
</types>
Prefixet cal används senare i message-elementen.
8. types (alternativ 2)
Ofta importerar man datatyperna från ett externt XML Schema. Detta är bra om din organisation redan har definierat sina datatyper i XML Schema och man vill återanvända dessa datatyper på ett smidigt sätt. Se exemplet nedan:
I detta exempel ser vi att vi inte använder något targetNamespace i schema-taggen. Istället definierar varje import-element sitt eget namnutrymme. Såhär ska man bara göra då schema endast innehåller importsatser.
<types>
<xsd:schema>
<xsd:import namespace="http://www.your_domain.com/ns/invoice"
schemaLocation="http://www.your_domain.com/schema/invoice.xsd" />
<xsd:import namespace="http://www.your_domain.com/ns/order"
schemaLocation="http://www.your_domain.com/schema/order.xsd" />
</xsd:schema>
</types>
9. message
Med detta element definierar man utgående, ingående och fel-meddelanden till operationerna i webbtjänsten. Ett meddelande kan innehålla en eller flera part-element. Ett part-element har två attribut med förvirrande lika funktion, nämligen type och element. Idén är att man bara ska använda antingen type eller element för varje enskilt part-element. Nedan beskrivs attributen för part närmare:
Attribut för message/part Beskrivning name Ett namn som beskriver part-elementet. Måste vara unikt bland sina syskon. type Detta attribut ska användas då webbtjänsten är dataorienterad (överför parametrar i form av data). Refererar till en datatyp, antingen en simpleType eller en complexType som är definierad i XML Schema. element Detta attribut ska användas då webbtjänsten är dokumentorienterad (överför dokument). element-attributet refererar också till en datatyp som definieras i ett XML Schema, men med skillnaden att attributets värde (själva datatypen) måste vara definierad innuti types-elementet för WSDL-filen. När man använder attributet element tvingar man transportprotokollet att skicka part-elementet i ett separat paket (för SOAP innebär detta att datatypen ligger ensam i soap:Body).
Se exemplet Calculator.wsdl:
I detta exempel används bara attributet type (eftersom vår webbtjänst är dataorienterad). Vi ser att vi använder två olika sorters datatyper:
<message name="MultiplicationRequest">
<part name="multiplicationRequestPart" type="cal:MultiplicationRequestType"/>
</message>
<message name="MultiplicationResponse">
<part name="multiplicationReturn" type="xsd:int"/>
</message>
<message name="DivisionRequest">
<part name="divisionRequestPart" type="cal:DivisionRequestType"/>
</message>
<message name="DivisionResponse">
<part name="divisionReturn" type="xsd:float"/>
</message>
<message name="DivideZeroException">
<part name="divideZeroError" type="xsd:string"/>
</message>
10. portType
Detta element representerar själva gränssnittet för en webbtjänst. Vanligtvis används bara ett portType-element i en WSDL-fil, det är helt enklet god sed att separera olika gränssnitt i olika filer. Vi tittar på ett exempel på hur ett portType-element kan se ut:
Vi ser att själva portType-elementet bara har ett attribut:
<portType name="CalculatorPortType">
<operation name="multiplication" parameterOrder="multiplicand multiplier">
<input message="tns:MultiplicationRequest" name="multiplicationRequest"/>
<output message="tns:MultiplicationResponse" name="multiplicationResponse"/>
</operation>
<operation name="division" parameterOrder="dividend divisor">
<input message="tns:DivisionRequest" name="divisionRequest"/>
<output message="tns:DivisionResponse" name="divisionResponse"/>
<fault message="tns:DivideZeroException" name="divideZeroException"/>
</operation>
</portType>
Attribut Beskrivning name I detta fall CalculatorPortType, vilket följer namnstandarden.
Vi ser att vi bara har operationer med både input och output-element för våra operationer. Det går även att definera operationer som tar bara input eller bara output, men input och output är trots allt det vanligaste. Vi ser att operationen division dessutom har ett fault-element. Detta element visar att denna metod kan kasta en speciell sorts undantag, nämligen divideZeroException.
11. binding
Elementet binding ansvarar för att binda den abstrakta beskrivningen av webbtjänsten som angavs i portType mot ett nätverksprotokoll.
I exemplet Calculator.wsdl binds portType-elementet mot SOAP över HTTP. Hur man gör detta beskrivs på sidan
SOAP binding för WSDL .
12. service
Service innehåller en grupp port-element (vanligtvis endast ett) som alla mappar ett binding-element mot en slutpunkt ("endpoint").
I vårt exempel ser service-taggen ut såhär:
Eftersom vi bara kommer att köra Calculator-applikationen lokalt mappar vi den mot localhost:8080. En riktig applikation bör mappas mot en publik URL.
<service name="CalculatorService">
<port binding="tns:CalculatorSoapBinding" name="Calculator">
<soap:address location="http://localhost:8080/axis/services/Calculator"/>
</port>
</service>