web|架构
最后,我给出对应本节描述的save_category元素的Schema定义的Schema图示来结束本小节。
Figure 1. SOAP API Schema图示
WSDL服务描述
对SOAP API消息完成Schema建模之后,一方面这个数据模型可以由SOAP Interface来使用,当发生具体调用时可以使用这个数据模型来除了传入的参数并生成传出的参数。同时,利用这个数据模型,我们可以生成相应的WSDL描述,从而将这个Web服务的接口文档发布给使用者,该接口文档是具备被程序自动处理的能力的。
以下是WSDL文档详细的定义:(完整的WSDL文档是: sagitta.wsdl)
<?xml version="1.0"?>
<definitions name="catalogService"
targetNamespace="http://www.sagitta.com/wsdl/savecategory.wsdl"
xmlns:tns="http://www.sagitta.com/wsdl/savecategory.wsdl"
xmlns:myxs="http://www.sagitta.com/schema/"
xmlns:soap="http://www.w3.org/2001/06/soap-envelope"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<import namespace="http://www.sagitta.com/schema/" location=" http://www.sagitta.com/schema/save_category.xsd" />
这是WSDL文件的文件头,其中的import元素指明在这个WSDL文件中,types系统是由http://www.sagitta.com/schema/save_category.xsd文件具体描述,在这里仅仅是将其导入。
<message name="save_category">
<part name="body" element="myxs:save_category"/>
</message>
<message name="categoryList">
<part name="body" element="myxs:categoryList"/>
</message>
这里定义了两条消息:save_category消息,在前面的Schema建模中已经完整地创建了根元素的结构定义。其中myxs是这里使用的命名空间(namespace),命名空间的具体定义在文件头上出现。而categoryList将会对应save_category消息的返回消息,在Schema建模中没有表现,在这里我也仅列出一个元素名,相信大家在看了本文的前半部分以及本系列的前一篇文章之后,会很清楚如何来定义。
<portType name="save_category_portType">
<operation name="save_category_operation">
<input message="tns:save_category"/>
<output message="tns:categoryList"/>
</operation>
</portType>
这部分定义了服务访问点的调用模式的类型,表明这个入口类型是请求/响应模式,请求消息是save_category,而响应消息是categoryList。
<binding name="save_category_soapBinding" type=" save_category_portType ">
<soap:binding transport=" http://www.w3.org/2001/06/soap-envelope/http">
<operation name="save_category_operation">
<soap:operation soapAction=" http://www.sagitta.com/catalog/">
<input>
<soap:body use="literal" namespace=" http://www.sagitta.com/schema/"
encoding http://www.w3.org/2001/06/soap-encoding"/>
</input>
<output>
<soap:body use="literal" namespace=" http://www.sagitta.com/schema/"
encoding http://www.w3.org/2001/06/soap-encoding"/>
</output>
</soap:operation>
</operation>
</soap:binding>
</binding>
这部分将服务访问点的抽象定义与SOAP HTTP绑定,描述如何通过SOAP/HTTP来访问按照前面描述的访问入口点类型部署的访问入口。其中规定了在具体SOAP调用时,应当使用的soapAction是"http://www.sagitta.com/catalog/",而请求/响应消息的编码风格都应当采用SOAP规范默认定义的编码风格" http://www.w3.org/2001/06/soap-encoding "。
<service name="catalogService">
<documentation>Online Web Service for Catalog</documentation>
<port name="save_category_port" binding="tns:save_category_soapBinding">
<soap:address location="http://www.sagitta.com/catalog/"/>
</port>
</service>
</definitions>
这部分是具体的Web服务的定义,在这个名为catalogService的Web服务中,提供了一个服务访问入口(其实还有很多,不过在这里因为演示的原因,仅仅介绍了一个),访问地址是"http://www.sagitta.com/catalog/",使用的消息模式是由前面的binding所定义的。
UDDI服务发布
在前一节中,我们已经通过使用WSDL这个工具将Catalog Service这个Web服务进行了结构化地描述。为了使更多的潜在用户能够发现这个Web服务,同时也为了加强这个Web服务的互操作能力和灾难恢复时的连接保持能力,我们需要使用UDDI SDK将这个Web服务注册到UDDI注册中心中去。
假设我们之前已经注册了一个businessEntity,叫做www.sagitta.com,一个在线服务提供商,这个businessEntity的键值是"434554F4-6E17-1342-EA41-36E642531DA1",那么我们要在这个businessEntity下注册一个businessService,以用于描述前面的Catalog Service。同时需要成立的假设是我们也预先注册了一个Service Type(tModel),这个tModel描述了我们这个需要发布的Web服务的调用规范,具体内容是前面我定义的这个WSDL文档,在UDDI中,注册的是描述的链接。
businessService注册的SOAP消息如下,其中使用了Microsoft的test.uddi.microsoft.com站点,因此authInfo中可以填入测试用的udditest。
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<save_service generic="1.0" xmlns="urn:uddi-org:api">
<authInfo>udditest</authInfo>
<businessService businessKey="434554F4-6E17-1342-EA41-36E642531DA1" serviceKey="">
<name>categoryService</name>
<description xml:lang="en">Online Web Service for Catalog</description>
<bindingTemplates>
<bindingTemplate bindingKey="" serviceKey="">
<description xml:lang="en">categoryService's BindingTemplate3</description>
<accessPoint URLType="http">http://www.sagitta.com/catalog/</accessPoint>
<tModelInstanceDetails>
<tModelInstanceInfo tModelKey="uuid:E31A569A-AEFF-4468-BA4D-2BF22FE4ACEF">
<description xml:lang="en">Sagitta Web Service Type Description</description>
<instanceDetails>
<description xml:lang="en">Sagitta Web Service Type Description</description>
<overviewDoc>
<description xml:lang="en">Sagitta Web Service Overview</description>
<overviewURL>http://www.sagitta.com/wsdl/savecategory.wsdl</overviewURL>
</overviewDoc>
</instanceDetails>
</tModelInstanceInfo>
</tModelInstanceDetails>
</bindingTemplate>
</bindingTemplates>
</businessService>
</save_service>
</Body>
</Envelope>
通过上述的API调用,我们就已经把这个服务注册进了UDDI注册中心,其中bindingTemplate的accessPoint是服务的入口,而overviewDoc中的overviewURL是WSDL文档的访问位置。
潜在的使用者可以通过查询UDDI注册中心找到这个Web服务,通过overviewURL中保存的URL找到服务的描述,然后通过accessPoint所指定的访问地址来访问这个服务。
当发生紧急服务崩溃的时候,Web服务可能被迁移到另一台主机上,IP地址,甚至是访问的URL都可能有很大变化,此时原先的集成的连接将不再工作。但是由于UDDI注册的存在,我们可以通过自动化的程序手段来解决这个问题,使得类似的服务灾难恢复的过程非常迅速。
具体的流程一般是:
当恢复的服务启动后,自动去更新UDDI注册中心上的数据,将访问入口修改到新的URL位置;
连入的客户端系统当发现无法访问最终服务的时候,将会定期去查询UDDI注册中心,看看新的BindingTemplate数据和本地缓存的有没有差别,如果有的话,就下载到本地,重新建立服务绑定,完成服务连接的迁移。
总结
到这篇文章为止,如何架构Web Service这个系列就将告一段落,在整个系列中,从为什么要有Web服务开始,到什么是Web服务,Web服务的开发工具,对Web服务作了一个概念上的全面介绍。然后以一个具体实例来介绍Web服务的构建模式和各种Web Service "stack"技术的具体应用。希望这个系列对大家理解和接受下一代的应用包装模式Web服务有一个全面的帮助。
参考资料
Web Service 技术/评论网站
UDDI-China.ORG, 以UDDI为主的Web服务技术网站。
WebServices.ORG, Web服务的综合类技术网站。
IBM developerWorks/Web Service Zone, IBM的Web服务技术资源中心
MSDN Online Web Services Developer Resources, Microsoft的Web服务的开发者资源网站
ITPapers/Web Service, ITPapers的Web服务评论文章
解决B2B电子商务应用交互和集成的InterOP Stack系列技术标准规范
UDDI执行白皮书, UDDI-China.org, UDDI.org
UDDI技术白皮书, UDDI-China.org, UDDI.org
UDDI程序员API规范, UDDI-China.org, UDDI.org
UDDI数据结构参考, UDDI-China.org, UDDI.org
Web Service Description Language (WSDL) 1.0, IBM, 25 Sep 2000
SOAP: Simple Object Access Protocol Specification 1.1, IBM, Microsoft, DevelopMentor, 2000
XML Schema Part 0: Primer , W3C, 2 May 2001
Extensible Markup Language (XML) 1.0 (Second Edition), W3C, 6 Oct 2000
作者简介
柴晓路: 上海得易电子商务技术有限公司(DealEasy)首席系统架构师、XML技术顾问。UDDI-China.org蓝色火焰工作室(Blue Blaze Studio)成员。UDDI Advisor Group成员,WSUI Working Group成员。2000年获复旦大学计算机科学硕士学位,曾在国际计算机科学学术会议(ICSC)、亚太区XML技术研讨会(XML Asia/Pacific'99)、中国XML技术研讨会(北京)、计算机科学期刊等各类国际、国内重要会议与期刊上发表论文多篇。专长于基于XML的系统集成和数据交换的技术研究,同时对数据库、面向对象技术及CSCW等技术比较擅长。