Let's take a look at the structure and working principle of a sample WSDL file. Note that this is just a simple WSDL document instance. Our goal is to briefly display the most significant features, which will be discussed in detail in the subsequent sections.
<?xml version="1.0" encoding="UTF-8" ?> <definitions name="FooSample" targetNamespace="http://tempuri.org/wsdl/" xmlns:wsdlns="http://tempuri.org/wsdl/" xmlns:typens="http://tempuri.org/xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:stk="http://schemas.microsoft.com/soap-toolkit/wsdl-extension" xmlns="http://schemas.xmlsoap.org/wsdl/"><types> <schema targetNamespace="http://tempuri.org/xsd" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" elementFormDefault="qualified" > </schema></types><message name="Simple.foo"> <part name="arg" type="xsd:int"/> </message><message name="Simple.fooResponse"> <part name="result" type="xsd:int"/> </message><portType name="SimplePortType"> <operation name="foo" parameterOrder="arg" > <input message="wsdlns:Simple.foo"/> <output message="wsdlns:Simple.fooResponse"/> </operation></portType><binding name="SimpleBinding" type="wsdlns:SimplePortType"> <stk:binding preferredEncoding="UTF-8" /> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="foo"><soap:operation soapAction="http://tempuri.org/action/Simple.foo"/><input> <soap:body use="encoded" namespace="http://tempuri.org/message/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /></input><output> <soap:body use="encoded" namespace="http://tempuri.org/message/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /></output> </operation> </binding><service name="FOOSAMPLEService"> <port name="SimplePort" binding="wsdlns:SimpleBinding"> <soap:address location="http://carlos:8080/FooSample/FooSample.asp"/> </port> </service> </definitions>
The following is a preview of the WSDL document:
The first line defines this document as an XML document. Although this line is not required, this line helps the XML parser to parse the WSDL document.
The second line defines the root element of the WSDL document: <definitions> and some namespace attributes are defined in the root element, which is similar to the <types> sub-element <schema>.
<Types> elements constitute a type segment. This segment may be ignored if no data type is to be defined. In the example WSDL, this section does not have a data type definition specific to the application, but still uses the type segment, only used to define the schema namespace used in this document.
<Message> the elements constitute the message segment. If you compare an operation to a function, the <message> element defines all parameters of the function. The <part> sub-element of each <message> corresponds to the parameter. The input parameter is defined in an independent <message> element, which is isolated from the output parameter. The output parameter is defined in its <message> element. The name attribute of the output parameter <message> element ends with "response" and is used to distinguish it from the input parameter. Each <part> element has the name and type attributes, just as the function parameters have the same type and name. <Part> the type attribute value of an element can be an XSD basic type, a soap-defined type, or a WSDL-defined type or a type defined by a type segment.
You can define zero, one or more <porttype> elements in the porttypes segment. This section can be excluded because it can be defined in an independent WSDL document. The example contains only one <porttype> element. <Porttype> the <operation> sub-element can be used to define one or more operations. The example contains only one <operation> element named "foo ". This name is equivalent to the function name. <Operation> An element can contain one, two, or three child elements: <input>, <output>, <fault>, the value of the message attribute in the three child elements corresponds to the <message> element in the message segment. The entire <porttype> element in the example is equivalent to int in C language.
Foo (INT Arg); function definition.
You can define zero, one or more <binding> elements in the binding segment. Its function is to specify how each <operation> request and response is transmitted over the network.
You can define zero, one or more <service> elements in the Services Section. The <service> element contains the <port> child element and corresponds to the <binding> element in the binding segment.
Namespace
Both the root element <definitions> and the child element <schema> have the namespace attribute.
Each namespace attribute defines the abbreviation of namespace in the document for each application. For example, "xmlns: XSD" defines xsd for http://www.w3.org/2001/xmlschemanamespace. After definition, you can use abbreviations in future documents to represent the complete namespace.
What is a namespace? Namespace is used to avoid name conflicts. If I create a web service and include an element with the name attribute Foo In the WSDL file. You are going to use this service with another service. If there is no namespace, the other service cannot include the "foo" name in its WSDL file. Each service can use the same name only when these names represent the same meaning in the same instance. Using different namespaces, the "foo" name in my own service can be the same as that in another service to indicate different meanings.
The targetnamespace attribute defines a namespace. All the names in the element belong to this namespace. In the example file, the targetnamespace attribute of the root element <definitions> is defined as http://tempuri.org/wsdl /. That is, all the names defined in this document belong to this namespace. The <schema> element has its own targetnamespace attribute and its value is http://tempuri.org/xsd. all the names defined in the <schema> element belong to the namespace rather than the upper-layer namespace.
<Schema> the default namespace (xmlns = "http://www.w3.org/2001/XMLSchema") is defined in the next row of the element, and all undefined names belong to this namespace.
SOAP message
One way to view a WSDL file is to use the file on the client and server, which determines the data transmitted over the network. Although soap uses the underlying IP address or HTTP protocol, the application determines the protocol used by the high-level on the client and server. In other words, if an operation is called "echoint", a simple Integer Operation is returned, the number of parameters, the type of each parameter, and how the parameters are transmitted over the network (serialization) the protocol defined by the application. Such a protocol can be specified in multiple ways, but I believe the best way is to use WSDL. If we review WSDL using this method, it is not only an interface contract, but also a Protocol definition language.
WSDL can define whether soap messages follow the RPC or document format. An RPC-style message, as defined in the example file, is like a function call with zero or multiple parameters. A document-style message is flat and requires only a small number of nested layers. The following XML message is the result sent and received after parsing the same WSDL file using soapclient object in MS soap Toolkit 2.0.
Initiate a function call "Foo (5131953)" from the client )":
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body><m:foo xmlns:m="http://tempuri.org/message/"> <arg>5131953</arg> </m:foo> </SOAP-ENV:Body></SOAP-ENV:Envelope>
Response received from the server:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body> <SOAPSDK1:fooResponse xmlns:SOAPSDK1="http://tempuri.org/message/"><result>5131953</result></SOAPSDK1:fooResponse></SOAP-ENV:Body> </SOAP-ENV:Envelope>
Function call messages and returned messages are both valid XML. A soap message includes an <envelope> element, which includes an optional XML schema in the WSDL type and message segment
The data type of WSDL is based on "XML Schema: PES ypes" (XSD), which is also recommended by W3C. The XSD document has three different versions (1999,200 0/10, and 2001). declare them in a namespace attribute of the <definitions> element and specify the version used in the special WSDL file.
Xmlns: XSD = "http://www.w3.org/2001/XMLSchema"
Prefix |
Equivalent namespace |
Description |
Soapenc |
Http://schemas.xmlsoap.org/soap/encoding |
Soap 1.1 ENC |
WSDL |
Http://schemas.xmlsoap.org/wsdl/soap |
The WSDL 1.1 |
XSD |
Http://www.w3.org/2001/XMLSchema |
XML Schema |
XSD defines two types of built-in types: basic and inheritance. For details, see: http://www.w3.org/TR/2001/PR-xmlschema-2-20010330
Complex types
XML Schema Allows defining complex types, which are represented by struct in C. For example, define the following C struct:
typedef struct { string firstName; string lastName; long ageInYears; float weightInLbs; float heightInInches;} PERSON;
Use XML schema to represent:
<xsd:complexType name="PERSON"> <xsd:sequence><xsd:element name="firstName" type="xsd:string"/><xsd:element name="lastName" type="xsd:string"/> <xsd:element name="ageInYears" type="xsd:int"/> <xsd:element name="weightInLbs" type="xsd:float"/> <xsd:element name="heightInInches" type="xsd:float"/></xsd:sequence> </xsd:complexType>
However, <complextype> can express functions that C struct cannot express. In addition to the <sequence> sub-element, other sub-elements are allowed. You can use <all> sub-element to replace <sequence>:
<xsd:complexType name="PERSON"> <xsd:all><xsd:element name="firstName" type="xsd:string"/><xsd:element name="lastName" type="xsd:string"/> <xsd:element name="ageInYears" type="xsd:int"/> <xsd:element name="weightInLbs" type="xsd:float"/> <xsd:element name="heightInInches" type="xsd:float"/></xsd:all> </xsd:complexType>
When <all> A child element appears, it indicates that its internal child elements can appear in any order and each child element is optional. This is not like C struct.
<Porttype> and <operation> Elements
A porttype defines several operations. The operation element in porttype defines the syntax for calling all methods in this porttype. Each operation element defines the method name, parameter (using the <message> element), and the type of each parameter (the <part> element defined in <message> ).
A wsdl document can contain multiple <porttype> elements. Each <porttype> contains a group of related operations.
Only one <input>, one <output>, and one <fault> element can appear in the <operation> element. Each element has the name and message attributes.
<Input>, <output>, <fault> what is the role of the name attribute of the three elements? It is used to distinguish (reload) the same operation name ).
<Binding> and <operation> Elements
The binding segment is used to fully define the protocol, serialization, and encoding in transmission. Therefore, the types, message, and port type segments are used to process the data content of the image, and the binding segment is used to define the physical details during transmission.
Separating a binding specification from data and messages means that service providers can standardize it to a set of operations (porttype) if they use the same business type ). Each provider can customize the binding according to its own requirements. This helps to separate the image definitions (types, message, and porttype) from the WSDL document and define them in an independent document, all service providers with the same business rules use the same image definition, while binding is customized. For example, a bank can define a set of standard bank operations and define them in a drawing WSDL document. Each bank can customize the protocol, serialization, and encoding.
The binding segment extracted from the example:
<binding name="SimpleBinding" type="wsdlns:SimplePortType"> <stk:binding preferredEncoding="UTF-8" /> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="foo"><soap:operation soapAction="http://tempuri.org/action/foo1"/> <input name="foo1"> <soap:body use="encoded" namespace="http://tempuri.org/message/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /></input> </operation> <operation name="foo"><soap:operation soapAction="http://tempuri.org/action/foo2"/> <input name="foo2"> <soap:body use="encoded" namespace="http://tempuri.org/message/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /></input> </operation> </binding>
The <binding> element has a name attribute (in this example, the value is "simplebinding"). This name is defined to reference it in the <port> element of the Services Section. The Type attribute references the <porttype> element. The second row is the extension element of mstk2, <STK: Binding>, specifying the preferred encoding type as UTF-8.
The <soap: Binding> element specifies the Message format (RPC) and transport. The transport attribute references a namespace to specify the http soap protocol.
Two <operation> elements have the same name "foo" and are distinguished by the name attribute of <input> elements, namely, "foo1" and "foo2 ". The <soap: Operation> element in the <operation> element contains the "soapaction" attribute, and its value is a URI. This URI is specified by the SOAP specification and used in the SOAP message. The SOAP message contains the soapaction message header and uses the URI in the <soap: Operation> element as its value. The soapaction attribute is only available in HTTP
Binding. The usage of this attribute is not very clear when writing this document. We recommend that the server use this attribute to route messages without parsing all messages. <Soap: Operation> You can also use the style attribute to overload the style attribute in <soap: Binding>.
<Operation> elements can contain <input>, <output>, and <fault> elements. These elements correspond to relevant elements in the porttypes segment. The preceding example only contains the <input> element. Each of these three elements has an optional name attribute. In this example, operations with the same name are distinguished. The <input> element in the example is the <soap: Body> element, which specifies the content of the SOAP message body. This element has the following attributes:
Use: This attribute specifies whether the data is encoded or literal. The literal meaning is that the data format in the SOAP message body is exactly the same as that in the profile definition (types, messages, and porttypes segments. Encoding indicates that the encoding is determined by the "encodingstyle" attribute value.
Namespace: Each SOAP message body can have its own namespace to avoid name conflicts. The URI specified in this attribute is completely used in the returned message.
Encodingstyle: Soap encoded, with the URI value "http://schemas.xmlsoap.org/soap/encoding"
Document binding
In the previous section, the value specified by the style attribute in the <soap: Binding> element is "RPC". When this attribute is specified as document, the data sequence in the transmission is changed, use Document Transmission instead of function signature. If this binding method is used, the <message> element defines the document format rather than the function signature. For example, consider the following WSDL snippet:
<definitions xmlns:stns="(SchemaTNS)" xmlns:wtns="(WsdlTNS)" targetNamespace="(WsdlTNS)"><schema targetNamespace="(SchemaTNS)" elementFormDefault="qualified"><element name="SimpleElement" type="xsd:int"/> <element name="CompositElement" type="stns:CompositeType"/><complexType name="CompositeType"><all> <element name='a' type="xsd:int"/> <element name='b' type="xsd:string"/></all> </complexType></schema><message...> <part name='p1' type="stns:CompositeType"/><part name='p2' type="xsd:int"/> <part name='p3' element="stns:SimpleElement"/> <part name='p4' element="stns:CompositeElement"/></message>...</definitions>
Schema has two elements: simpleelement and compositelement. The latter type is compositetype. The unique <message> element defines four parts: P1; Type: compositetype; P2; Type: int; P3: simpleelement; and P4: compositeelement. The following shows the transmission formats of the four binding methods determined by style/use:
RPC/literal
<operation name="method1" style="rpc" ...> <input> <soap:body parts="p1 p2 p3 p4" use="literal" namespace="(MessageNS)"/> </input> </operation>
Format in the SOAP message:
<soapenv:body... xmlns:mns="(MessageNS)" xmlns:stns="(SchemaTNS)"><mns:method1> <mns:p1><stns:a>123</stns:a> <stns:b>hello</stns:b> </mns:p1> <mns:p2>123</mns:p2> <mns:p3><stns:SimpleElement>123</stns:SimpleElement> </mns:p3> <mns:p4> <stns:CompositeElement> <stns:a>123</stns:a> <stns:b>hello</stns:b> </stns:CompositeElement> </mns:p4></mns:method1> </soapenv:body>
RPC/encoded
<operation name="method1" style="rpc" ...> <input> <soap:body parts="p1 p2" use="encoded" encoding="http://schemas.xmlsoap.org/soap/encoding/" namespace="(MessageNS)"/> </input> </operation>
Format in the SOAP message:
<soapenv:body... xmlns:mns="(MessageNS)"> <mns:method1> <p1 HREF="#1" TARGET="_self"/> <p2>123</p2></mns:method1> <mns:CompositeType id="#1"> <a>123</a> <b>hello</b> </mns:CompositeType> </soapenv:body>
Document/literal/Type
<operation name="method1" style="document" ...> <input> <soap:body parts="p1" use="literal"> </input> </operation>
Format in the SOAP message:
<soapenv:body... xmlns:stns="(SchemaTNS)"> <stns:a>123</stns:a> <stns:b>hello</stns:b> </soapenv:body>
Document/literal/Element
<operation name="method1" style="document" ...> <input> <soap:body parts="p3 p4" use="literal"> </input> </operation>
Format in the SOAP message:
<soapenv:body... xmlns:stns="(SchemaTNS)"> <stns:SimpleElement>123</stns:SimpleElement> <stns:CompositeElement> <stns:a>123</stns:a> <stns:b>hello</stns:b> </stns:CompositeElement> </soapenv:body>
Document/encoded
<operation name="method1" style="document" ...> <input> <soap:body parts="p1 p2" use="encoded" encoding="http://schemas.xmlsoap.org/soap/encoding/" namespace="(MessageNS)"/> </input> </operation>
Format in the SOAP message:
<soapenv:body... xmlns:mns="(MessageNS)"> <mns:CompositeType> <a>123</a> <b>hello</b></mns:CompositeType> <soapenc:int>123</soapenc:int> </soapenv:body>
<Service> and <port> Elements
A service has a set of <port> elements. Each <port> element has a one-to-one correspondence with binding. If multiple <port> elements are associated with the same <binding>, you must specify an optional location.
<service name="FOOService"> <port name="fooSamplePort" binding="fooSampleBinding"><soap:address location="http://carlos:8080/fooService/foo.asp"/></port> </service>