描述与注册 发布Web服务(二)

日期: 2008-09-26 作者:柴晓路 来源:TechTarget中国 英文

  这是category元素类型的描述,任何使用product类型的文档元素可以包含的子元素是name、description、category和product。name和description元素的类型都是简单类型xs:string。而category是一个递归元素,引用了自身这个元素类型。而product的元素类型则是前面描述好的product类型。任何使用product类型的文档元素还有两个必须出现的属性categoryKey和parentCategoryKey,这是两个字符串(xs:string)类型的属性值,分别表示了自身元素的键值和父辈category的键值。


   <xs:element name=”save_category”>
      <xs:complexType>
        <xs:sequence>
          <xs:element name=”authInfo” type=”xs:base64Binary”/>
          <xs:element name=”category” type=”category” minOccurs=”0″ maxOccurs=”unbounded”/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
 
  这是在这个Schema文档中唯一的一个元素定义,元素save_category是一个复合类型,它的元素可以有authInfo和category。其中authInfo是一个base64编码的字符串,而category则是一个可以出现0次到无限次的类型为category的子元素。我们不难发现元素定义和类型定义的基本机制是一样的,事实上,我们完全可以将这段定义拆分成两段,一段为类型定义,一段为元素定义,下面给出这个等价实例,希望有助于对Schema的理解。


   <xs:complexType name=”save_category”>
      <xs:sequence>
        <xs:element name=”authInfo” type=”xs:base64Binary”/>
        <xs:element name=”category” type=”category” minOccurs=”0″ maxOccurs=”unbounded”/>
      </xs:sequence>
    </xs:complexType>
    <xs:element name=”save_category” type=”save_category” />
 
  那为什么要采用第一种方法,而不使用第二种方法呢,原因也很简单,由于整个Web服务相关的消息Schema中,诸如category、product、featureBag、compliantSpecBag、parameterBag这些元素都可能被复用,因此定义成类型比较合适,而save_category是一个单一的消息,不可能被其他元素复用,因此就直接定义成了元素。


  </xs:schema>
 
  最后,我给出对应本节描述的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”
               
            
            
             >
    <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 style=”document” 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/”
                         encodingStyle=”   http://www.w3.org/2001/06/soap-encoding”/>
            </input>
            <output>
              <soap:body use=”literal” namespace=”   http://www.sagitta.com/schema/”
                         encodingStyle=”   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 >
    <Body>
      <save_service generic=”1.0″ >
        <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服务有一个全面的帮助。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐