一月份写的文章,由于工作比较忙,最后一点还没有写完。今天翻草稿箱的时候发现了。发表了吧。剩下那点什么时候用到了再补上。懒了懒了...
这篇文章将要向大家介绍 WSDL 规范和 WSDL 的 BPEL 扩展规范。
在读这篇文章之前,你应该知道:
1. Web Service 是什么?
2. WSDL 是什么?它是干什么用的?
3. SOAP 是什么?
4. XML Schema 和 XML Namespace 的知识
要了解这些内容,你可以登陆 http://www.w3schools.com。
对于这篇文章的内容,有人会有这样的疑问:我们需要了解 WSDL 的内容吗?单就设计 Web Service 而言,我们有很多框架工具可以使用,例如 Java 方面的 Axis2 和 CXF(其它编程语言也有类似的框架工具)。这些工具使得我们可以完全不去了解 WSDL 的内容便可以实现一个 Web Service。但是对于 BPMS 的设计,我们需要 BPEL 和 WSDL 的相互配合。也许在 BPM Designer 领域,有这样的产品可以使我们完全不去知道 BPEL 和 WSDL 的内容便可以设计 BPMS。但这个目标没有完全被实现,有时我们还需要在代码级别进行设计。况且,知其然更要知其所以然。
第一部分:WSDL 概览
<definitions targetNamespace="XXX"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:XXX="XXX">
<import namespace="XXX" location="XXX.wsdl" />
...
<types>
<xs:schema elementFormDefault="qualified"
targetNamespace="XXX">
<xs:complexType name="XXX">
<xs:sequence>
<xs:element name="XXX" type="xs:string" />
...
</xs:sequence>
</xs:complexType>
<xs:simpleType name="XXX">
<xs:restriction base="xs:string">
...
</xs:restriction>
</xs:simpleType>
</xs:schema>
</types>
<message name="XXX">
<part name="XXX" type="XXX:XXX" />
...
</message>
<!-- Abstract Part -->
<portType name="XXX">
<operation name="XXX">
<input message="XXX:XXX" />
<output message=XXX:XXX"" />
</operation>
</portType>
...
<!-- End -->
<!-- Concrete Part -->
<binding name="XXX" type="XXX:XXX">
<operation>
...
</operation>
...
</binding>
<service>
<port>
...
</port>
...
</service>
<!-- End -->
<!-- Partner Link -->
<plnk:partnerLinkType name="travelLT">
<plnk:role name="travelService">
<plnk:portType name="tns:TravelApprovalPT" />
</plnk:role>
<plnk:role name="travelServiceCustomer">
<plnk:portType name="tns:ClientCallbackPT" />
</plnk:role>
</plnk:partnerLinkType>
<!-- End -->
</definitions>
注:XXX表示的内容是自定义的,但并不代表是相同的
上面的是 WSDL 的一个概览。先大体介绍每部分。
- <import>: 用于导入其它 WSDL 文件。
- <types>: 使用 XML Shema 定义 WSDL 其余部分所用到的数据类型。
- <message>: 相当于编程语言中的变量定义。在更早一点的 WSDL 版本中(可能是 1.0 版的,可以在 IBM developWorks 的文章中看到使用这个版本 WSDL 的文章),<container> 元素的作用和 <message> 一样。
- <portType>: 在 WSDL 2.0 中它换了个新名字 <interface>。<portType> 就像一个包,它里面包含很多操作接口定义。显然新名字更形象。
- <operation>: <portType> 的子元素。它定义的只是操作的接口定义。也就是说,通过它,你只能知道这个操作从外面看是什么样。而这个操作是如何进行的,这不是它的职责。<portType> 和 <operation> 被称为 WSDL 的 Abstract 部分。(什么意思,我不想什么都说,搞编程的应该知道这是什么意思)
- <binding>: 从上面的代码看,binding 中的东西不多。原因是 <binding> 元素的作用是将 <portType> 和其中的 <operation> 绑定到特定的协议上面。所以 <binding> 里面的内容会由于协议的不同而有不同的内容,故我省略了很多的东西。
- <service>: 这个元素的内容是描述 <portType> 中定义的操作是如何实现的。它和 <binding> 由于涉及到了 Web Service 的具体的实现问题,所以被称为 WSDL 的 Concrete 部分。
- <plnk:pertnerLinkType>: 它以及它的子元素是对在 BPEL 中所要用到的 partner 的定义。
第一部分:types 和 message
第二部分:Abstract Part: portType 和 operation
上面这两部分很简单,暂时不说,大家去
W3Schools 上自己看就足够了。
portType 的命名规则:比较常见的命名法是按照驼峰命名法命名,但是结尾要加上PT(大写)。
第三部分:Concrete Part: binding 和 service
binding
前面已经说过了,<binding> 的作用是将 <portType> 中定义的操作绑定到特定的协议上。也就是告诉相应的客户端用什么协议和服务器通信。WSDL 1.1 声明了两种可用于绑定的协议:一种是 SOAP,另一种是 HTTP GET 或 POST。
SOAP 是最常用的 Web Service 通信协议,所以 WSDL 和 SOAP 经常在一起出现,以至于很多初学者认为 WSDL 和 SOAP 是绑定在一起的。
下面这段代码是如何使用 SOAP 协议进行绑定的示例代码:
<binding name="XXX" type="tns:XXX">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />
<operation name="CreateTracker">
<soap:operation
soapAction="XXX"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />
<input>
<soap:body parts="XXX"
use="literal"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />
</input>
<output>
<soap:body parts="XXX"
use="literal"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" />
</output>
</operation>
</binding>
接下来详细解释这段代码。
<binding> 元素有两个属性。第一个属性是 name,这个属性用于表示 <binding>,可以任起,但最好是有意义的名字(什么样的意义后面说)。第二个属性是 type 的内容是要和一个你想为其定义绑定的 <portType> 的 name 有关的的。组成法是这样的:tns:portType's name。在这里第一次出现了 tns 命名空间。
关于 tns:tns 的意思是 TargetNameSpace。它是和 WSDL 根元素的 targetNameSpace 属性的内容一致的。当然你可以不用 tns 这个名字,换另外一个名字,理论上这时可以的。但 tns 是一个约定好的命名。
接下来的元素就是 <soap:binding>。对示例代码中 <soap:binding> 的语言描述就是使用 document 风格的 soap 绑定当前 portType(style 属性),按照 http 协议传输 soap (transport 属性)。最后,定义 soap 命名空间。
- style 属性:此属性定义了 SOAP 绑定是 document 风格还是 rpc 风格。关于风格的选择,我会在后面结合 <soap:body> 的 use 属性加以解释。
- transport 属性:用于定义 SOAP 消息按照什么协议传输。本例中使用 HTTP 协议传输。也可以选择 FTP、SMTP 等协议传输。
- xmlns:soap:这是一个命名空间的定义,但为什么放在这里呢?而不是文档的头部。上面这段示例代码来自 ActiveBPEL。我认为在这里出现 XML 命名空间的定义很可笑。在 WSDL 1.1 的 Specification 中也没有出现类似的用法。欢迎大家对此发表意见。
第四部分:BPEL Part: partnerLinkType