14.4 XML和WSDL

WSDL是Web Service Description Language 4个单词的首字母缩写,它表示Web Service描述语言。WSDL文档被Web Service提供商用于描述自身提供的Web Service,Web Service调用者可根据该WSDL文档调用Web Service提供的服务。

WSDL文档依然是一份平台无关的XML文档,用于描述、定位网络上提供的Web Service,它详细定义了Web Service的位置、该Web Service所提供的操作(或方法),以及调用这些操作(或方法)的方式。

2001年3月,WSDL 1.1由IBM和Microsoft作为一个W3C记录(W3C note)提交给W3C组织,用于描述网络服务。

2002年7月,W3C发布了第一个WSDL 1.2工作草案。

2007年6月,W3C发布了最新的WSDL 2.0版本。

由于现在大量的Web Service服务都是基于WSDL 1.1定义的,因此本书将侧重于介绍WSDL 1.1版本的内容。

14.4.1 WSDL基本语法

WSDL模型充分运用了规范和实现分离的原则,将Web Service的服务接口和服务实现分成两个部分定义。

WSDL的第一个部分定义了服务接口,它由<message…/>和<portType…/>两个元素组成。其中<message…/>元素定义了操作的交互方式;而<portType…/>元素里则可包含任意数量的<operation…/>子元素,每个<operation…/>元素代表一个允许远程调用的操作(即方法)。

WSDL的第二个部分定义了服务实现,它由<binding…/>和<service…/>两个元素组成。其中<binding…/>元素定义使用特定的通信协议、数据编码模型和底层通信协议,将Web Service服务接口定义映射到具体实现;而<service…/>元素则包含一系列的<port…/>子元素,<port…/>子元素会把绑定机制、服务访问协议和端点地址结合在一起。

图14.6为WSDL文档的概念模型。

alt

图14.6 WSDL文档的概念模型

图14.6显示了WSDL 1.1的模型图,通过该图可以更清楚地看到WSDL 1.1中允许出现的元素。

下面是笔者开发的一个Web Service所对应的WSDL文档:

alt

alt

alt

alt

alt

14.4.2 portType元素

<portType…/>元素用于描述一个Web Service所有可以被调用的操作,以及与该操作相关的消息。每个<portType…/>元素可以包含N个<operation…/>子元素,每个<operation…/>子元素定义一个允许被远程调用的操作。


alt提示

<portType…/>在WSDL 2.0中已被改名为<interface…/>,从该名称即可看出,该元素用于定义Web Service的访问接口,读者可以将该元素当成传统编程语言中的一个函数库(或一个模块、一个类),而每个<operation…/>子元素则可当成传统编程语言中的一个函数(或一个方法)。


WSDL定义了4种类型的操作,如表14.2所示。

表14.2 WSDL定义的4种类型操作

alt

从表14.2可以看出,4种不同类型的操作所对应的<operation…/>元素可以包含的子元素也不相同,图14.7显示了<operation…/>元素的内部结构。

alt

图14.7 operation元素的内部结构

位于<operation…/>元素内部的<input…/>元素和<output…/>元素都必须指定一个message属性,该message属性的值必须是前面定义的<message…/>元素的name属性值。例如,前面的WSDL中定义的所有<operation…/>都是request-response操作,每个操作都对应如下结构的代码:

alt

如果只是定义一个one-way操作,则在<operation…/>元素内只需一个<input…/>元素即可,如以下WSDL片段所示:

alt

14.4.3 binding元素

<binding…/>元素用于定义Web Service与某个具体的网络传输协议或消息传输协议之间的绑定。例如,我们既可将<portType…/>定义的Web Service与SOAP/HTTP绑定,也可将其与MIME/SMTP绑定。

<binding…/>元素有以下两个常用属性:

alt name属性:指定<binding…/>元素的名称。

alt type属性:指定为哪个<portType…/>元素定义的Web Service进行绑定。该属性的值必须等于前面定义的<portType…/>元素的name属性值。

<binding…/>元素的内部结构如图14.8所示。

alt

图14.8 binding元素的内部结构

在<binding…/>元素内部,只有N个<operation…/>元素是固定的,它用于完成该Web Service里各操作和具体实现之间的绑定,这种绑定通常采用SOAP绑定扩展。

WSDL 1.1包括用于SOAP 1.1的绑定规范,SOAP绑定扩展位于http://schemas.xmlsoap.org/ wsdl/soap/命名空间之下。在该命名空间下主要定义了以下4个元素:

alt soap:address:用于为Web Service指定具体的网络地址。该元素通常作为<service…/>元素的<port…/>子元素的子元素使用。

alt soap:binding:用于为Web Service指定底层传输协议(由transport属性指定)和通信风格(由style属性指定)。SOAP提供了两种常用的通信风格:① 面向远程过程调用的rpc风格;②面向消息的document风格。面向消息的document风格更为灵活和强大,因此更适合Web Service松耦合的特性,除了可用于同步请求/响应调用之外,也可用于异步消息传递,通常优先考虑使用面向消息的document风格。

alt soap:operation:用于为Web Service所包含的操作提供更详细的信息,通常可指定该操作的SOAP Action头(由soapAction属性指定)。

alt soap:body:用于指定SOAP消息在<body…/>元素里以怎样的形式表现(使用use属性指定)。SOAP提供了两种常用的表现形式:① 直接的文本方式(use="literal");② SOAP编码方式(use="encoded")。

例如,上面的WSDL示例中的代码片段:

alt

14.4.4 service元素

<service…/>元素用于为Web Service提供的访问入口指定详细的部署细节。由于每个<service…/>元素可以定义多个服务访问入口,因此每个<service…/>元素都可以包含多个<port…/>子元素,每个<port…/>子元素定义一个服务访问入口。

图14.9为<service…/>元素的内部结构:

alt

图14.9 service元素的内部结构

<service…/>元素内部的<port…/>子元素需要指定以下两个属性:

alt name属性:指定<port…/>元素的名称。

alt type属性:指定为哪个<binding…/>元素定义的绑定指定服务访问入口。该属性的值必须等于前面定义的<binding…/>元素的name属性值。

<port…/>子元素内部通常还会定义一个<soap:address…/>子元素,该子元素可以指定一个location属性,其值就是该服务访问入口的网络地址。

14.4.5 WSDL和UDDI

在Web Service提供商将自己的Web Service暴露完成之后,WSDL文档也正确描述了它所提供的Web Service,但Web Service的使用者如何才能发现这些服务呢?因此Web Service提供商还需要将自己开发的Web Service进行发布、广而告之,这就需要借助于UDD(IUniversal Description Discovery and Integration)了。

UDDI本质上是一种公共的目录服务,Web Service提供商通过UDDI来注册自己的Web Service,而Web Service使用者通过UDDI来搜索所需的Web Service。

在互联网上,所有行业、企业以及个人用户都愿意选择支持UDDI,之后,这些行业、企业以及个人都可通过UDDI来得益:互联网上所有行业、企业以及个人都可通过Web Service提供服务,并通过提供某种服务来赢利;互联网上所有行业、企业以及个人都可使用Web Service服务,并通过使用某种服务获得便利。

UDDI的前景是非常美好的,它希望企业之间通过UDDI提供的公共目录服务,动态地发现并调用互联网上提供的服务。但这基于一个假设:所有企业都愿意动态地建立和其他企业之间的业务关系,即使以前二者并无合作关系。这个假设在现实生活中却遇到了极大的困难,因此UDDI并没有获得真正的成功。2005年12月,IBM、Microsoft和SAP停止了面向公众开放的UDDI注册中心。


alt提示

读者可以把UDDI注册中心想象成一种特制的“企业黄页”,当某个公司需要某种Web Service时就通过翻阅该“企业黄页”来查找,然后去调用该Web Service。因此制作这本“企业黄页”需要所有企业通力合作,否则它就无法真正制作成功。


由于UDDI实际上并没有赢得广泛的支持,然而Web Service的注册和发现依然是非常重要的,因此新的标准和产品正在不断出现。

由于UDDI在实际应用中的缺席,因此不同企业之间通过Web Service进行交互的可能性依然不大。但在某个企业内部的不同部门之间,不同平台的异构系统之间,却可以广泛地使用Web Service相互通信。这很容易理解:虽然外部的UDDI注册中心没有得到广泛支持,但在企业内部,所有部门、所有开发者可以非常方便地了解对方所能提供的Web Service,因而可以非常方便地调用它们。