转:http://blog.youkuaiyun.com/posonrick/article/details/45580355
作为webservice客户端开发,在日常工作中可能经常会拿到一个对方提供的wsdl地址或文档,那么拿到这个地址后我们如何编写客户端调用代码呢,前面几篇只是以个人经验的方式写了下,那么真正要根据wsdl文档来编写客户端调用代码就必须学会看懂wsdl文档。下面就结合之前基础篇的demo来深入剖析下wsdl文档,最后以图解的方式形象说明下。
本文以之前基础篇的SayHello的Demo来深入分析下wsdl文档的几个部分,个人认为可以共分6部分,下面分别介绍:
<definitions/>
这部分在基础篇里已经介绍,主要说明引用了哪些schema以及schema的位置等,可以看下基础篇的介绍,SayHello的Demo这部分内容如下:
- <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service.server.ws.devins.com/"
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http"
- xmlns:ns1="http://service.server.ws.devins.com/" name="SayHelloImplService"
- targetNamespace="http://impl.service.server.ws.devins.com/">

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service.server.ws.devins.com/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http"
xmlns:ns1="http://service.server.ws.devins.com/" name="SayHelloImplService"
targetNamespace="http://impl.service.server.ws.devins.com/">
<types/>
- <!--
- types
- schema:约束xml格式
- element:用来指定xml中的标签
- <sayHello></sayhello>
- <sayHelloResponse></sayHelloResponse>
- complexType:说明是一个复合类型
- 请求
- <sayHello>
- <arg0>string</arg0>
- </sayhello>
- 响应
- <sayHelloResponse>
- <return>string</return>
- </sayHelloResponse>
- 回看下demo的请求与响应的核心内容
- <q0:sayHello>
- <arg0>devins</arg0>
- </q0:sayHello>
- <ns2:sayHelloResponse">
- <return>Hello: devins</return>
- </ns2:sayHelloResponse>
- -->
- <wsdl:types>
- <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:tns="http://service.server.ws.devins.com/" elementFormDefault="unqualified"
- targetNamespace="http://service.server.ws.devins.com/" version="1.0">
- <xs:element name="sayHello" type="tns:sayHello" />
- <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
- <xs:complexType name="sayHello">
- <xs:sequence>
- <xs:element minOccurs="0" name="arg0" type="xs:string" />
- </xs:sequence>
- </xs:complexType>
- <xs:complexType name="sayHelloResponse">
- <xs:sequence>
- <xs:element minOccurs="0" name="return" type="xs:string" />
- </xs:sequence>
- </xs:complexType>
- </xs:schema>
- </wsdl:types>

<!--
types
schema:约束xml格式
element:用来指定xml中的标签
<sayHello></sayhello>
<sayHelloResponse></sayHelloResponse>
complexType:说明是一个复合类型
请求
<sayHello>
<arg0>string</arg0>
</sayhello>
响应
<sayHelloResponse>
<return>string</return>
</sayHelloResponse>
回看下demo的请求与响应的核心内容
<q0:sayHello>
<arg0>devins</arg0>
</q0:sayHello>
<ns2:sayHelloResponse">
<return>Hello: devins</return>
</ns2:sayHelloResponse>
-->
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://service.server.ws.devins.com/" elementFormDefault="unqualified"
targetNamespace="http://service.server.ws.devins.com/" version="1.0">
<xs:element name="sayHello" type="tns:sayHello" />
<xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
<xs:complexType name="sayHello">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="sayHelloResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<message/>
- <!--
- message:用来定义soap消息结构
- part:部分/组成的意思
- 实际上引用的就是上面schema中的约束格式
- -->
- <wsdl:message name="sayHelloResponse">
- <wsdl:part element="ns1:sayHelloResponse" name="parameters" />
- </wsdl:message>
- <wsdl:message name="sayHello">
- <wsdl:part element="ns1:sayHello" name="parameters" />
- </wsdl:message>

<!--
message:用来定义soap消息结构
part:部分/组成的意思
实际上引用的就是上面schema中的约束格式
-->
<wsdl:message name="sayHelloResponse">
<wsdl:part element="ns1:sayHelloResponse" name="parameters" />
</wsdl:message>
<wsdl:message name="sayHello">
<wsdl:part element="ns1:sayHello" name="parameters" />
</wsdl:message>
<portType/>
- <!--
- portType:用来指定服务器端的SEI(接口)
- operation:表示操作/行为,即SEI中定义的方法
- input:方法sayHello的输入
- output:方法sayHello的输出
- 输入输出引用的是上面message的定义
- -->
- <wsdl:portType name="ISayHello">
- <wsdl:operation name="sayHello">
- <wsdl:input message="ns1:sayHello" name="sayHello" />
- <wsdl:output message="ns1:sayHelloResponse" name="sayHelloResponse" />
- </wsdl:operation>
- </wsdl:portType>

<!--
portType:用来指定服务器端的SEI(接口)
operation:表示操作/行为,即SEI中定义的方法
input:方法sayHello的输入
output:方法sayHello的输出
输入输出引用的是上面message的定义
-->
<wsdl:portType name="ISayHello">
<wsdl:operation name="sayHello">
<wsdl:input message="ns1:sayHello" name="sayHello" />
<wsdl:output message="ns1:sayHelloResponse" name="sayHelloResponse" />
</wsdl:operation>
</wsdl:portType>
<binding/>
- <!--
- binding:用来指定SEI的实现类
- type属性:引用<portType>定义
- <soap:binding style="document">:表示传输的一个document (xml)
- <input><output>与上节说的相同
- <soap:body use="literal" />:表示body传输采用文本即xml格式的文本
- -->
- <wsdl:binding name="SayHelloImplServiceSoapBinding" type="ns1:ISayHello">
- <soap:binding style="document"
- transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="sayHello">
- <soap:operation soapAction="" style="document" />
- <wsdl:input name="sayHello">
- <soap:body use="literal" />
- </wsdl:input>
- <wsdl:output name="sayHelloResponse">
- <soap:body use="literal" />
- </wsdl:output>
- </wsdl:operation>
- </wsdl:binding>

<!--
binding:用来指定SEI的实现类
type属性:引用<portType>定义
<soap:binding style="document">:表示传输的一个document (xml)
<input><output>与上节说的相同
<soap:body use="literal" />:表示body传输采用文本即xml格式的文本
-->
<wsdl:binding name="SayHelloImplServiceSoapBinding" type="ns1:ISayHello">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document" />
<wsdl:input name="sayHello">
<soap:body use="literal" />
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<service>
- <!--
- service:相同于webservice容器,也可理解为一个工厂
- name:用于指定客户端的容器类/工厂类,客户端代码从此类开始
- port:用来指定服务器端的一个入口(对应SEI的实现类)
- port binding:引用上面定义的
- port name:容器通过这个方法获得实现类
- address:客户端真正用于请求的地址
- 回想我们的demo:
- SayHelloImplService factory = new SayHelloImplService();
- SayHelloImpl sayHelloImpl = factory.getSayHelloImplPort();
- -->
- <wsdl:service name="SayHelloImplService">
- <wsdl:port binding="tns:SayHelloImplServiceSoapBinding"
- name="SayHelloImplPort">
- <soap:address location="http://132.122.239.74:8089/ws/sayhello" />
- </wsdl:port>
- </wsdl:service>

<!--
service:相同于webservice容器,也可理解为一个工厂
name:用于指定客户端的容器类/工厂类,客户端代码从此类开始
port:用来指定服务器端的一个入口(对应SEI的实现类)
port binding:引用上面定义的
port name:容器通过这个方法获得实现类
address:客户端真正用于请求的地址
回想我们的demo:
SayHelloImplService factory = new SayHelloImplService();
SayHelloImpl sayHelloImpl = factory.getSayHelloImplPort();
-->
<wsdl:service name="SayHelloImplService">
<wsdl:port binding="tns:SayHelloImplServiceSoapBinding"
name="SayHelloImplPort">
<soap:address location="http://132.122.239.74:8089/ws/sayhello" />
</wsdl:port>
</wsdl:service>
以上就webservice基础篇里的SayHello为例,详细对wsdl进行了剖析,最后再结合上面的分析以图示的方式形象展现下,希望对需要深入理解wsdl文档的朋友有一定帮助。
图解WSDL
根据WSDL文档中的几部分,以及各部分之间的引用关系,下面以图例的方式展现如下:
说明:上图中的箭头表示引用关系。