账号:
密码:
最新动态
产业快讯
CTIMES / 文章 /
剖析WSDL的架构与实作
 

【作者: 姚巧玫、胡百敬】2004年12月01日 星期三

浏览人次:【5659】

WSDL 1.0(Web Services Description Language 1.0)是在2000年9月发表,用以取代Microsoft先前提出的SCL(SOAP Contract Language,SCL)与IBM倡导的NASSL,它用一种和具体程序语言无关的抽象方式定义Web服务(Web Service)呼叫和响应有关的操作和讯息。


WSDL 2.0协议目前已经被提交给因特网标准组织W3C(World Wide Web Consortium)审查,目前还处于「草案」状态i。SOAP1.1与WSDL1.1目前在因特网标准组织W3C的规范属性均属Notes状态,WSDL 1.2才是真正由W3C主导的规范,但目前仍在草案阶段,草案版也已在因特网标准组织W3C网站中可以查询到。


W3C维持着正规的标准化系统同时,提交提案必须经过确定的一套批准过程才能最终成为官方协议。由于网络服务与平台的提供者,如微软、IBM、升阳...等,有责任将欲提供的Web服务利用本规范制作成为一个WSDL文件,而制作的过程可藉由许多它们所支持的工具来协助完成。因此,虽然规格尚未成为标准,但我们已经可以透过.NET、Java等不同平台上的开发工具来建立Web服务,而这些平台也都可以产生彼此理解的服务规格描述:WSDL。


WSDL的本质

WSDL(Web Service Description Language)是以XML的XSD格式撰写而成,由于XML是极为严谨的语言,如此一来可减少错误的产生。Web服务在本质上应可与其他不同的协议共同运作,惟在现阶段WSDL 1.1规范中是以SOAP、HTTP GET/POST及MINE运作为主。用来描述服务的提供者提供了哪些服务,正确的数据传递格式,以及如何存取这些服务。


就其定义来说,不能仅仅把WSDL当作一种对象接口定义语言,例如,CORBA或COM等应用程序结构就会用到对象接口定义语言IDL(Interface Description Language)。WSDL保持协议中立,但它确实内建了对SOAP通讯协议的支持,从而与SOAP建立了不可分割的联系。利用WSDL的服务描述语言可清楚地定义沟通接口与位置,然后透过SOAP通讯协议,便可以将用户端与Web服务呼叫往返的讯息包装成XML格式的文件。


此外,它也包含了以往COM世界IDL的功能。当前端用户要存取这个服务时,需要了解呼叫服务会用到哪些型别、有哪些函数可以呼叫、函数的参数型别、回传数据型别、透过什么样的协议可以存取、以及在哪里可以取得服务等等,这些都是WSDL需要描述的。简单的说,WSDL就是用来描述一个Web服务能做什么?位置在哪?如何呼叫?


WSDL重要性

为什么需要WSDL?这的确是个好问题。想象一下以下没有WSDL的情形,每当我们要使用一个Web服务时,就利用E-mail或电话询问提供服务的厂商该如何使用网络上的服务,若是每家提供服务的厂商没有固定存取数据的格式,则会有更多无法预期的状况发生,因为即使我们依照所给的数据来使用Web服务,也都会有可能发生无法预期的错误,例如,某个产品的编号是13579,别以为它是一个数值型态的数据,实际上它却是一个字符串型态的数据,在这种情况之下,错误就因此而产生了;除了细节的处理问题外,最主要的困难仍是不方便及不标准制式化。


WSDL具有可延伸性,可透过名称领域(namespace)的定义拓展其应用,无论用户实行何种网络协议与讯息格式,WSDL皆可描述其端点(end point)与讯息。WSDL会要求传送的讯息应该包含那些信息,以及响应的讯息应该使用那种方式,再加上目前大部分的WSDL档案都可以由应用程序或执行平台来产生,所以对服务提供商来说,将可省去撰写WSDL档案的麻烦,而对服务需求者而言,也可由开发工具来读入WSDL档案,然后产生使用Web服务时所需的代理程序。


WSDL档案在服务导向架构中的定位及关系可以由(图一)来阐释,透过WSDL档案,服务需求者可以知道如何使用这个Web服务,但前提是Web服务提供商必须要提供这个WSDL档案才行。也就是说,当服务提供商对外公布它所提供的网络服务时,它必须先建立一个描述Web服务的WSDL档案,然后在注册Web服务到UDDI注册中心的同时,也一并将这个WSDL档案予以注册。如此一来,服务需求者在经由UDDI注册中心取得网络服务信息时,也能够同时取得用来描述此网络服务的WSDL档案。无论三者间是何种作业,彼此沟通的方式都是使用SOAP协议。WSDL不仅只是描述网络服务,它也肩负提供信息给服务需求者在服务请求中的SOAP内容及UDDI注册中心的部份信息,因此WSDL还涉及了绵密的解译及对应架构。


《图一 Web Service的基本功能》
《图一 Web Service的基本功能》

WSDL定义、架构

Web服务描述语言的架构是由XML语言所组成,藉由XML Schema来界定文件内的元素、属性等数据,进而达成「描述」Web服务(应用程序)之目的。WSDL文件将网络服务定义为服务的端点(end point)或埠(port)的集合,亦即实际执行应用程序的位置,在XML Schema中使用六个主要元素,如(图二)


  • 1.数据类型集(Types):定义讯息交换时,会用到的数据型别。


  • 2.讯息(Message):描述需要沟通的讯息。


  • 3.接口定义(Port Type):一组操作行为,以及该行为会用到的讯息。


  • 4.服务链结(Binding):定义不同行为实际沟通的协议细节,以及如何把前述抽象的讯息结构化为实体的传输格式。除此之外,在这个部分,也可以定义如果执行中,出现错误时,应该如何响应!


  • 5.服务端点(Port):binding与网络位置合起来定义的端点(end point)


  • 6.实作服务(Service):将相关的port群组在一起。



《图二 WSDL文件主要组成元素的分类》
《图二 WSDL文件主要组成元素的分类》

图二的右侧是说明WSDL内六个主要元素的排列,其中前四个元素相当于「接口描述」,后二个元素则相当于「执行描述」。也可以说WSDL的六个主要元素其实可大分为接口描述与执行描述两项,接着我们分别就接口描述及执行描述的顺序说明六个主要元素。WSDL文件以元素<definitions>为XML根节点(Root Element),而WSDL文件的基本结构如下:



<definitions命名空间的定义>

<types>
types 的定义...
</types>

<message>
messages 的定义...
</message>

<portType>
port 的定义...
</portType>

<binding>
binding 的定义...
</binding>

<service>
<port 指定 binding>
指定端点
<port>
</service>

</definitions>

另外,继承了XML本身的特色,WSDL文件也可以包含其他延伸的元素。而service元素让它可以群组多个web服务的定义放在单一的WSDL文件中。


WSDL实做范例

以下就简单地描述一个Web服务所对应的WSDL,而笔者透过Visual Basic.NET所撰写的Web服务程序范例定义如下:



Imports System.Web.Services
Imports System.Xml.Serialization
<XmlRoot("Employee")>_
Public Class Employee
'前端所看到的Employee对象属性将是LName,FName
'Title而不是LastName,FirstName,Title
<XmlElement("LName")> Public LastName As String
<XmlElement("FName")> Public FirstName As String
<XmlElement("Title")> Public Title As String
End Class
<WebService(Namespace:="http://myDemo/")>
Public Class Service1
    Inherits WebService
<WebMethod()> Public Function GetEmployee( _
    ByVal intI As Integer) As Employee
        Dim emp As New Employee()
emp.LastName = "胡"
emp.FirstName = "百敬"
emp.Title = "顾问"
        Return emp
    End Function
End Class

这个程序代码列表(1)描述回传对象结构的Web Service。


当我们透过ASP.NET撰写如程序代码列表(1)的Web服务后,对应上述的六大部分,检视.NET Framework为该Web服务自动建立的WSDL如下。因为透过ASP.NET/.NET Framework 1.0所撰写的Web服务自动支持三种叫用方式:SOAP、HTTP GET、HTTP POST,所以WSDL同一类的数据大都有为三种存取方式撰写不同的描述,但.Net Framework 1.1默认把HTTP GET/POST方法停用了,你需要自行到machine.config内启动Web服务对HTTP GET/POST沟通协议的支持。笔者在此处故意要有三种协议的Web服务沟通方式,让你可以对WSDL的内容有一个比较:


首先是根元素<definitions>:



<definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="http://myDemo/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://myDemo/" xmlns="http://schemas.xmlsoap.org/wsdl/">

在根元素中,可以看到大量以下各元素可能会用到的命名空间。在根元素之后的是<types>元素。接着是定义传入传出哪些数据型别,因为GetEmployee方法传入的参数是一个整数,所以types元素内对应的定义如下:



<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intI" type="s:int" />
</s:sequence>
</s:complexType>

而GetEmployee方法回传的数据型别是Employee类别,因此描述数据格式如下:



<s:complexType name="Employee">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="LName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="FName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string" />
</s:sequence>
</s:complexType>

上述的XSD是定义Employee类别经过XML串行化后的结构,你可以与该类别串行化的结果做一个比对,这也就是实际透过SOAP传递的对象个体。笔者撷取用户端程序与Web服务沟通的内容如下所示:


<Employee xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns=http://myDemo/>
<LName>胡</LName>
<Fname>百敬</FName>
<Title>顾问</Title>
</Employee>

types将数据型别分别对应到函数呼叫的参数与回传数据型别,定义如下:


<s:element name="GetEmployee">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="intI" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetEmployeeResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Employee" nillable="true" type="s0:Employee" />
</s:sequence>
</s:complexType>
</s:element>

其中属性name与函数同名的是代表输入参数,如上述的GetEmployee。在函数名称后加上Response代表的是函数回传的数据型别,如上述的GetEmployeeResponse。


message元素

types元素所描述的「参数本身的数据结构,搭配上方法的输出入方向后的数据结构」与传递的协议无关。其后可接收的讯息应该也与使用何种协议并无直接关系,但因为用何种协议会影响实际可传递的讯息结构,例如以SOAP协议呼叫Web Service时,可以传递对象当作输入参数,但若是以HTTP Get/Post呼叫Web Service,则只能传递简单的数据型别。所以Web Service可用的讯息就被分为好几种,内容如下:



<message name="GetEmployeeSoapIn">
<part name="parameters" element="s0:GetEmployee" />
</message>
<message name="GetEmployeeSoapOut">
<part name="parameters" element="s0:GetEmployeeResponse" />
</message>
<message name="GetEmployeeHttpGetIn">
<part name="intI" type="s:string" />
</message>
<message name="GetEmployeeHttpGetOut">
<part name="Body" element="s0:Employee" />
</message>
<message name="GetEmployeeHttpPostIn">
<part name="intI" type="s:string" />
</message>
<message name="GetEmployeeHttpPostOut">
<part name="Body" element="s0:Employee" />
</message>

若我们在程序代码列表(1)的GetEmployee函数,输入的参数是对象型别,例如就是程序代码列表(1)内定义的Employees,则上述有关HttpGet与HttpPost的两个部分就会消失,因为透过HttpGet和HttpPost呼叫Web Service时,无法传递对象当作传入参数,自然就不会有此讯息。


另外,若详细一点观察可以发现Soap的这一组讯息,输出入的对应都是parameters 元素,数据结构的定义则是我们自定的,所以xsd使用的命名空间是s0,也就是代表在程序代码列表(1)中,我们以WebService Attribute替类别Class1所定义的命名空间http://myDemo/,这个别名的对应是定义在根元素<definitions>上。


而HttpGet或HttpPost在传入参数时,只能用简单的资料型态,透过对应到命名空间http://www.w3.org/2001/XMLSchema的s,可以知道这些简单资料型别是W3C定义的。而它们回传的内容可以是资料节构,所以是“s0:Employee”,并放在Http封包的Body部分。


portType元素

在服务接口(port Type)中,主要是定义各项Web服务抽象逻辑上的操作行为,以及该行为用到的讯息。主要是数据输入与数据输出定义。WSDL规格上四种端点讯息沟通模式定义如下:


  • ●接受服务(one-way):使用端点接收讯息


  • ●寻求/响应(request/response):端点接受讯息、并送出相关讯息


  • ●请求/响应(solicit/response):端点送出讯息、并接收相关服务


  • ●通知(notification):用户送出讯息



虽然规格上描述了四种讯息往返的模式,但一般来说我们撰写的Web服务方法只有前两种,也就是用户端呼叫,但没有传回值,以及用户端呼叫后,该方法有传回值。


Web服务的提供者一次可以提供多种Web服务,同一个Web服务可以支持多种协议让前端程序存取。这里描述每一种协议存取该Web服务时,可以用哪一种前述的Message,因此这个元素也等于在定义逻辑的通讯端口(port)。上述程序代码列表1的因为是一般的函数,所以port Type元素的范例采用的是「寻求/响应」模式如下:



<portType name="Service1Soap">
<operation name="GetEmployee">
<input message="s0:GetEmployeeSoapIn" />
<output message="s0:GetEmployeeSoapOut" />
</operation>
</portType>
<portType name="Service1HttpGet">
<operation name="GetEmployee">
<input message="s0:GetEmployeeHttpGetIn" />
<output message="s0:GetEmployeeHttpGetOut" />
</operation>
</portType>
<portType name="Service1HttpPost">
<operation name="GetEmployee">
<input message="s0:GetEmployeeHttpPostIn" />
<output message="s0:GetEmployeeHttpPostOut" />
</operation>
</portType>

假若你所撰写的Web Service内某个方法传入的参数是对象型别,则HttpGet和HttpPost两个呼叫方式无法支持,在其内的operation子元素就不会出现该方法。operation元素下的input和output所指定的message,则是在前一个message区段所定义的message元素。


binding元素

定义完逻辑的联络埠后,接着要定义每个埠的实体存取方式,也就是透过不同协议要实际存取到该服务时,所需的细节内容。范例如下:



<binding name="Service1Soap" type="s0:Service1Soap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<operation name="GetEmployee">
<soap:operation soapAction="http://myDemo/GetEmployee" style="document" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<binding name="Service1HttpGet" type="s0:Service1HttpGet">
<http:binding verb="GET" />
<operation name="GetEmployee">
<http:operation location="/GetEmployee" />
<input>
<http:urlEncoded />
</input>
<output>
<mime:mimeXml part="Body" />
</output>
</operation>
</binding>
<binding name="Service1HttpPost" type="s0:Service1HttpPost">
<http:binding verb="POST" />
<operation name="GetEmployee">
<http:operation location="/GetEmployee" />
<input>
<mime:content type="application/x-www-form-urlencoded" />
</input>
<output>
<mime:mimeXml part="Body" />
</output>
</operation>
</binding>

在上方SOAP的区段内,定义了HTTP表头内的SOAP Action项目的内容是http://myDemo/GetEmployee,数据内容编码的方式是document而非rpc,参数编码的方式literal而非encodedii。相对于HTTP Get方式的存取,HTTP所使用的动词是GET而非POST,参数传递的方式要经过url编码。当然你可以将HTTP GET与POST的区段做一个比较,就可以大概了解binding元素要描述的内容。


service元素

提供上述各存取协议逻辑埠,实际要存取Web服务的端点(endpoint),主要是说明如何进行由服务接口所提供的服务,包括提供服务的名称、内容及服务的网络位置等。



<service name="Service1">
<port name="Service1Soap" binding="s0:Service1Soap">
<soap:address location="http://localhost/GetWSDL/Service1.asmx" />
</port>
<port name="Service1HttpGet" binding="s0:Service1HttpGet">
<http:address location="http://localhost/GetWSDL/Service1.asmx" />
</port>
<port name="Service1HttpPost" binding="s0:Service1HttpPost">
<http:address location="http://localhost/GetWSDL/Service1.asmx" />
</port>
</service>

结论

上述文件中,实体的端点,也就是以port元素描述是采用哪一种沟通方式,就直接以name属性指定之前port Type元素内所定义的埠名称,而binding属性则指定之前binding元素所定义与通讯协议相关的联机细节。而address元素则指定实体存取的路径。


综合以上各段,若提供的Web Service可以用不同的方式存取,如ASP.NET所提供的Web Service默认可以用SOAP、HTTP Get和HTTP Post三种方式存取,则所提供的服务会参照到三种逻辑连接的埠(port Type)定义,每个埠有不同的链接细节(binding),逻辑埠可以传递不同的讯息(message),每种讯息包含不同的数据型态(types)。


延 伸 阅 读
WSDL 1.0依其功能与应用详述说明。相关介绍请见「WSDL 1.0延伸数据 」一文。
WSDL 2.0功能与应用举例详述说明。你可在「WSDL 2.0延伸数据」一文中得到进一步的介绍。
针对rpc/document和literal/encoded 之间的差异加以说明。在「rpc/document、literal/encoded的差异 」一文为你做了相关的评析。
相关组织网站

WSDL官方网站

W3C官方网站

升阳公司网站
相关文章
用Arduino 打造机器人:循迹、弹钢琴、下棋都行!
树莓派推出AI摄影机、新款显示器
智慧充电桩百花齐放
充电站布局多元商业模式
以爆管和接触器驱动器提高HEV/EV电池断开系统安全性
comments powered by Disqus
相关讨论
  相关新闻
» 台达推出5G ORAN小型基地台 实现智慧工厂整合AI应用
» 欧洲航太技术展在德国盛大展开,全球吸睛 镭洋推出卫星通讯整合方案,目标抢占庞大的欧洲卫星商机
» 经济部促成3GPP大会来台争话语权 国内外大厂共商5G/6G新一代技术标准
» 经济部支持跨国研发有成 台欧双方分享B5G~6G规划
» 达梭系统收购IQMS扩展3DEXPERIENCE平台


刊登廣告 新聞信箱 读者信箱 著作權聲明 隱私權聲明 本站介紹

Copyright ©1999-2024 远播信息股份有限公司版权所有 Powered by O3  v3.20.1.HK8564I1N3GSTACUKS
地址:台北数位产业园区(digiBlock Taipei) 103台北市大同区承德路三段287-2号A栋204室
电话 (02)2585-5526 #0 转接至总机 /  E-Mail: webmaster@ctimes.com.tw