SilenceCliff

导航

Web Service:你需要多熟悉?(1)

 

Part1: 缘起

 

     在上次的讨论中,我们跟随大师Don BoxC++游历到 COM,再从COM游历到CLR。一路而来,我们似乎领会到越来越多组件话编成的味道。这不禁让我勾起了些许联想。组件——Component,这个被业界已经喧嚣叫嚷了太多年的概念。从C++中的源代码复用,到Win32OLECOM的到来,到CORBA……

     走在二十一世纪的初期,时下的编成语言早已不是昔日类似C甚至Assembly那样孱弱的组件特性了。不错,肯定有许多人会为C甚至Assembly申辩。但凭心而论,现代的高级语言早已经不再是Eric S. Raymond所推崇备至的像C语言那样的薄薄的一层。他们和那浩繁巨大的API库为我们干了太多的事情,我们需要操心底层的越来越少,但我们所拥有的控制却并非少了。

在这蛮荒之时,走向组件化最重要的就是规避差异

这些差异从何而来?

CPU来!从OS来!从编程语言来!从语义来!

为什么一个语言写的代码不能轻易的成为一个可重用的组件?这里困难主要来自CPUOS,数据类型在不同的CPU上有不同的存储格式!语言的运行时环境或者代码本身依赖于OS提供的专属API,于是自然你的代码被绑定在了特定的CPU & OS 组合的平台上。用CC++等等原生高级语言(这类语言主要特征是:直接和OS打交道,如手动管理内存,借助平台特性进行线程管理,直接编译成特定平台的机器代码,平台间移植困难重重)编写的应用大多头符合上述两个特征。这也正是上个世纪90年代Win32风靡时,人人追捧微软那8万多API的缘由。在那个年代,一个操作系统的API确实占据举足轻重的地位。正如史蒂夫·鲍尔默在微软PDC大会上那样急切的期盼:“开发者!开发者!开发者!开发者!”。正是因为太多的Windows应用才真正撑起了Win32MFC满天飞时的那个微软帝国!在这当中OS API扮演了很重要的角色。这也是那个原生语言时代的必然。

逃离OS!几乎是所有反微软的共同心声。程序语言的进步使这成为了可能。基于虚拟机的编程语言,在OS和编程语言之间增加了一层间接性——虚拟机(VM)!如果让VM及至的简化,那就是当年原生语言下的语言运行时(RunTime)!VM的出现就是为了规避来自CPUOS的差异。这样一个新的间接层的出现,使得代码在跨越这些平台复用成为了可能!然而VM的出现甚至能解决各种编程语言之间的差异(这种差异更多的表现再类型系统上)!这两者最典型的代表分别是:JVMCLR。一个支持跨平台,但到来今天,在JVM上面跑的语言岂止JAVA啊!beanshellgroovypythonruby如雨后春笋在JVM这个大观园里百花齐放!而CLR早已不是像微软一厢情愿的那样只在Windows下开花结果,Linux/Unix下猴子(Mono)搅扰了微软的黄粱美梦。由此也可窥见一二的是:即便厂商各自的策略不同,但规避差异的潮流会让它们渐渐趋同的。

值得多提的,是规避各种编程语言的差异所带来的一些麻烦。上面我说,CLR规避了各种编程语言之间的差异。但事实上它的能力是有限的!它基于它内部的CTS(公共类型系统),各种编程语言特有的类型是不能在语言之间交互的。也就是说,横梗在各种语言之间的最大困难就是:复杂类型的映射!

无论是IL(中间语言)还是byte-code它们描述特定语言类型的能力都不是最好的!而这个时候,历史的机遇走在了XML的当口。它的出现,如山洪般迅猛势足!或者在我看来用下面这个论点来解释其获得广泛巨大成功的原因:具备很好的描述性!XMLHTML而来,摆脱了狭隘桎梏般的几个标签,把描述权还归给开发者,XML的出现注定使它成为一种元语言!或者这样讲,XML作为一种语言本身来讲的话,它孱弱乏力。但作为一种元语言,它则变作了一个强有力的内核和引擎!使用XML来描述复杂的类型系统成为一种很必然的选择走上了IT历史的舞台!

在这些为之努力的人当中,不得不说的还是Don Box.。他早期在微软的辛勤工作,为SOAP规范的制定做出了卓越的贡献!SOAP就是在XML Schema出现之前使用XML描述复杂类型系统映射的一次具有开创意义的尝试。然而也正是因为SOAP自身早于XML Schema出现,也给现今的XML Web Service的使用带来了更多的复杂和混乱。在SOAP之后,在XML自身的DTD的演化下,XML Schema规范发布。这是一个非常重要的关于类型在XML中如何建模的规范!它的出现也是Web Service应运而生的必要前提!

除了规避差异,使组件可重用之外,我们也更希望一直快捷的使用方式,而不是烦笨的拷贝分发。通过Web进行链接那正是我们想要的!所以在这个时代,我们可以说:“链接就是API!!!”。在Web上,我们现成可用的就是如TCPSMTPHTTP等等协议。

于是,历史走到这个端口,一切都呼之欲出:HTTPXMLXML SchemaSOAP

 

 

Part2: 历史的明线

 

WSDL——Web 服务描述语言。这个用XML进行描述的一个规范!在那些支持协议上终于让组件编程能够跨越了CPUOSProgramming Language之间的鸿沟,使便捷的组件交互成为了可能。

 

在上一部份中,我们从组件编程的角度谈了谈Web Service的发展之路!现在我们换一个角度来看Web Service

 

RPC——远程过程调用,这是一个有相当年龄的词汇!早在面向对象语言大行其道之前,它早已如雷贯耳。在70年代那些基于COBOL构建的大型商业应用中,过程语言的RPC早已应用自如。等到了面向对象语言成为主流的今天,远程方法调用(RMI)依然在分布式编程领域占着很重要的位置!Web Service的出现大有该朝换代之势。从保守的眼光来看,Web Service不过是一个新的远程方法调用技术。然而我们应当发现消息与调用,方法(过程)与操作之间那微妙的差别。从更具颠覆意义的层次看,Web Service决不是单纯的远程方法调用。正基于这个原因,在Web Service中分为两大派系:架构流派和方法流派。

 

无疑,Don Box肯定是站在方法流派这边的。这和他早期的经历是密不可分的。早期在C++COM的职业经历使Don Box在制定SOAP规范时就是为了解决在C++COM中出现的许多问题,它依然保持着很浓烈的远程方法调用的味道!在SOAP.1规范中的第5节和第7节更是使这种风格在整个规范中打上了深深的烙印。(SOAP规范的第5节描述了一套用于编码数据类型的XML(包括对多态类型的编码)。第7节则描述了如何将方法调用的响应模拟成XML结构。在使用Web Service时,当使用第5节和第7节一起用于模拟方法调用时,这种类型的SOAP通常被称为Rpc/Encoded SOAP

 

两种流派的斗争也使得后来的互操作性话题变得那么异常艰难!回想CORBA因标准下各种实现不兼容而被弃用之前事,Web Service的处境也并非毫无隐患。Rpc/Encoded SOAPWeb Service的互操作性中就扮演着这样一样讨人厌的角色。

 

 

Part3: 规范要义

 

玄而不实谓之为空。我们在这里精简的浏览下与web service攸关的重要协议并呈清一些常见的误解。

WSDL——一种用来描述Web Service的基于XML的语言。其主要目标是可扩展性、抽象性和结构化。

可扩展性

在设计一个XML Schema的时候,使用元素代替属性最好的地方就是:元素的表现力和可扩展性。你可以为元素扩展一个属性来包含额外的数据。

WSDL在它的<binding>部分钟使用了这个功能非常强大的扩展机制。这可以让你创建新的标准,扩展WSDL文档的强大功能。如BPEL,利用这些扩展描述操作与服务之间的控制方式。

    抽象性

   WSDL允许和高级别的抽象。它定义的是抽象术语:消息和操作。只有它后来的<binding><service>元素部分才会讨论具体的信息。如SOAPActionHTTP端点。

结构

Web Service是基于XML的,而XML是一种高度结构化的元语言。就一般情况,Web Service是高度结构ua的消息和消息模式。WSDL提供了一种方式,对这种消息操作的复杂性和消息及其操作的模式进行建模。

 

WSDL的一个原则就是:牺牲简单的语法换取更好的表达式和功能性。WSDL主要分两个部分,其中一部分是抽象的,另一部份是具体的。

抽象部分包括<types><message><portType>元素部分。在这里,我们能得到的只是关于数据、消息和相关操作的单纯信息。在这里,消息是从一个进程发送到另一个进程的一些数据。操作是表示整套的相关消息的消息组合。但实际的消息格式,即包括它正使用SOAPHTTP之类的信息,仍然是未知的。

这样的好处在于,我们可以制定多种具体的方法来发送和接收这些消息。

WSDL文档的<binding>  <service>部分指定了所有相关的具体信息,在任何具体操作中,我们需要使用具体的信息来发送消息。

下面是BanCa中规则引擎所发布的Web ServiceWSDL文档:

 

   <?xml version="1.0" encoding="UTF-8" ?>

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://endpoint.service.newbiz.webservice.banca.gelc.com" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns3="http://billcard.domain.banca.gelc.com" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" targetNamespace="http://endpoint.service.newbiz.webservice.banca.gelc.com">

<wsdl:types xmlns:ns1="http://customer.domain.banca.gelc.com" xmlns:ns2="http://product.domain.banca.gelc.com">

<xsd:schema targetNamespace="http://billcard.domain.banca.gelc.com" elementFormDefault="qualified" attributeFormDefault="qualified">

- <xsd:complexType name="Policy">

- <xsd:sequence>

  <xsd:element name="backDate" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="benefiteds" type="ns1:ArrayOfBenefited" minOccurs="0" nillable="true" />

  <xsd:element name="chargeType" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="errorCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="holdDate" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="holder" type="ns1:Holder" minOccurs="0" nillable="true" />

  <xsd:element name="insurancePlanning" type="ns2:InsurancePlanning" minOccurs="0" nillable="true" />

  <xsd:element name="insured" type="ns1:Insured" minOccurs="0" nillable="true" />

  <xsd:element name="pass" type="xsd:boolean" minOccurs="0" />

  <xsd:element name="remark" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="sendCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="specialSpecification" type="xsd:string" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

  </xsd:schema>

<xsd:schema targetNamespace="http://product.domain.banca.gelc.com" elementFormDefault="qualified" attributeFormDefault="qualified">

- <xsd:complexType name="InsurancePlanning">

- <xsd:sequence>

  <xsd:element name="bankaccount" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="bankcode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="paymode" type="xsd:int" minOccurs="0" />

  <xsd:element name="productInfo" type="ns2:ProductInfo" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="ProductInfo">

- <xsd:sequence>

  <xsd:element name="bonuschoise" type="xsd:int" minOccurs="0" />

  <xsd:element name="firstTotal" type="xsd:double" minOccurs="0" />

  <xsd:element name="products" type="ns2:ArrayOfProduct" minOccurs="0" nillable="true" />

  <xsd:element name="total" type="xsd:double" minOccurs="0" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="ArrayOfProduct">

- <xsd:sequence>

  <xsd:element name="Product" type="ns2:Product" nillable="true" minOccurs="0" maxOccurs="unbounded" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="Product">

- <xsd:sequence>

  <xsd:element name="amount" type="xsd:double" minOccurs="0" />

  <xsd:element name="calcDirection" type="xsd:int" minOccurs="0" />

  <xsd:element name="chargePeriod" type="xsd:int" minOccurs="0" />

  <xsd:element name="chargeType" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="count" type="xsd:int" minOccurs="0" />

  <xsd:element name="insurancePeriod" type="xsd:int" minOccurs="0" />

  <xsd:element name="jobPrem" type="xsd:float" minOccurs="0" />

  <xsd:element name="master" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="normalPrem" type="xsd:double" minOccurs="0" />

  <xsd:element name="productCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="productName" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="weakPrem" type="xsd:float" minOccurs="0" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="ArrayOfInformFact">

- <xsd:sequence>

  <xsd:element name="InformFact" type="ns2:InformFact" nillable="true" minOccurs="0" maxOccurs="unbounded" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="InformFact">

- <xsd:sequence>

  <xsd:element name="answer" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="answers" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="informQuestion" type="ns2:InformQuestion" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="InformQuestion">

- <xsd:sequence>

  <xsd:element name="fulltext" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="questionId" type="xsd:int" minOccurs="0" />

  </xsd:sequence>

  </xsd:complexType>

  </xsd:schema>

<xsd:schema targetNamespace="http://customer.domain.banca.gelc.com" elementFormDefault="qualified" attributeFormDefault="qualified">

- <xsd:complexType name="ArrayOfBenefited">

- <xsd:sequence>

  <xsd:element name="Benefited" type="ns1:Benefited" nillable="true" minOccurs="0" maxOccurs="unbounded" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="Benefited">

- <xsd:sequence>

  <xsd:element name="benefiteRate" type="xsd:float" minOccurs="0" />

  <xsd:element name="certiType" type="xsd:int" minOccurs="0" />

  <xsd:element name="customerInfo" type="ns1:CustomerInfo" minOccurs="0" nillable="true" />

  <xsd:element name="order" type="xsd:int" minOccurs="0" />

  <xsd:element name="relationship" type="xsd:int" minOccurs="0" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="CustomerInfo">

- <xsd:sequence>

  <xsd:element name="age" type="xsd:int" minOccurs="0" />

  <xsd:element name="birthday" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="certiCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="gender" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="name" type="xsd:string" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="Insured">

- <xsd:sequence>

  <xsd:element name="address" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="certiType" type="xsd:int" minOccurs="0" />

  <xsd:element name="company" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="companyphone" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="customerInfo" type="ns1:CustomerInfo" minOccurs="0" nillable="true" />

  <xsd:element name="email" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="height" type="xsd:float" minOccurs="0" />

  <xsd:element name="informs" type="ns2:ArrayOfInformFact" minOccurs="0" nillable="true" />

  <xsd:element name="job" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="jobclass" type="xsd:int" minOccurs="0" />

  <xsd:element name="marriage" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="mobile" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="relationship" type="xsd:int" minOccurs="0" />

  <xsd:element name="telephone" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="weight" type="xsd:float" minOccurs="0" />

  <xsd:element name="zip" type="xsd:string" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

- <xsd:complexType name="Holder">

- <xsd:sequence>

  <xsd:element name="address" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="certiType" type="xsd:int" minOccurs="0" />

  <xsd:element name="company" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="companyphone" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="customerInfo" type="ns1:CustomerInfo" minOccurs="0" nillable="true" />

  <xsd:element name="email" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="height" type="xsd:float" minOccurs="0" />

  <xsd:element name="informs" type="ns2:ArrayOfInformFact" minOccurs="0" nillable="true" />

  <xsd:element name="job" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="jobclass" type="xsd:int" minOccurs="0" />

  <xsd:element name="marriage" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="mobile" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="relationship" type="xsd:int" minOccurs="0" />

  <xsd:element name="telephone" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="weight" type="xsd:float" minOccurs="0" />

  <xsd:element name="zip" type="xsd:string" minOccurs="0" nillable="true" />

  </xsd:sequence>

  </xsd:complexType>

  </xsd:schema>

<xsd:schema targetNamespace="http://endpoint.service.newbiz.webservice.banca.gelc.com" elementFormDefault="qualified" attributeFormDefault="qualified">

- <xsd:element name="underWriting">

- <xsd:complexType>

- <xsd:sequence>

  <xsd:element name="in0" type="ns3:Policy" nillable="true" minOccurs="1" maxOccurs="1" />

  </xsd:sequence>

  </xsd:complexType>

  </xsd:element>

- <xsd:element name="underWritingResponse">

- <xsd:complexType>

- <xsd:sequence>

  <xsd:element name="out" type="ns3:Policy" nillable="true" minOccurs="1" maxOccurs="1" />

  </xsd:sequence>

  </xsd:complexType>

  </xsd:element>

  </xsd:schema>

  </wsdl:types>

<wsdl:message name="underWritingResponse">

  <wsdl:part name="parameters" element="tns:underWritingResponse" />

  </wsdl:message>

<wsdl:message name="underWritingRequest">

  <wsdl:part name="parameters" element="tns:underWriting" />

  </wsdl:message>

<wsdl:portType name="RulePortType">

<wsdl:operation name="underWriting">

     <wsdl:input name="underWritingRequest" message="tns:underWritingRequest" />

     <wsdl:output name="underWritingResponse" message="tns:underWritingResponse" />

  </wsdl:operation>

</wsdl:portType>

<wsdl:binding name="RuleHttpBinding" type="tns:RulePortType">

    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:operation name="underWriting">

           <wsdlsoap:operation soapAction="" />

<wsdl:input name="underWritingRequest">

                     <wsdlsoap:body use="literal" />

             </wsdl:input>

<wsdl:output name="underWritingResponse">

  <wsdlsoap:body use="literal" />

  </wsdl:output>

      </wsdl:operation>

 </wsdl:binding>

<wsdl:service name="Rule">

<wsdl:port name="RuleHttpPort" binding="tns:RuleHttpBinding">

          <wsdlsoap:address location="http://localhost:8088/BanCaWS/service/RuleEngine" />

     </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

 

类型

 

<types>部分描述了文档剩余部分将会参照的数据类型。在这个部分, WSDL是相当的灵活,一般该部分的类型描述采用XML Schema,但你也可以采用其他的模式语言对类型进行描述,比如Relax NG。在采用XML Schema的类型描述时,一般为了获得最大的互操作性,我们可以在命名空间中包含“XML Schema 2001文档。

一个截取自上面文档的例子:

<xsd:complexType name="Policy">

<xsd:sequence>

  <xsd:element name="backDate" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="benefiteds" type="ns1:ArrayOfBenefited" minOccurs="0" nillable="true" />

  <xsd:element name="chargeType" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="errorCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="holdDate" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="holder" type="ns1:Holder" minOccurs="0" nillable="true" />

  <xsd:element name="insurancePlanning" type="ns2:InsurancePlanning" minOccurs="0" nillable="true" />

  <xsd:element name="insured" type="ns1:Insured" minOccurs="0" nillable="true" />

  <xsd:element name="pass" type="xsd:boolean" minOccurs="0" />

  <xsd:element name="remark" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="sendCode" type="xsd:string" minOccurs="0" nillable="true" />

  <xsd:element name="specialSpecification" type="xsd:string" minOccurs="0" nillable="true" />

 </xsd:sequence>

</xsd:complexType>

 

消息

 

值得强调一点:WSDL并不只是关于远程方法调用的。WSDL可以描述 RPC,但它可以描述消息和操作。消息和操作与方法调用相似,但并不是完全一样。

一个消息的示例如下:

<wsdl:message name="underWritingResponse">

     <wsdl:part name="parameters" element="tns:underWritingResponse" />

</wsdl:message>

<wsdl:message name="underWritingRequest">

     <wsdl:part name="parameters" element="tns:underWriting" />

</wsdl:message>

 

 

端口类型和操作

 

portTypeWeb Service实例的一种抽象定义。<portType>部分包含相关操作的集合,而这些操作又是相关消息的集合。通常,我们看到的是制定一条输入消息和一条输出消息,这样的特征和RPCHTTP的工作方式十分相仿。

但值得呈清的便是:这不是消息编组到操作的唯一方式。在WSDL中定义了4种不同的数据传输类型,它们分别是:

Ø         One-Way

Ø         Request-Response

Ø         Solicit-Response

Ø         Notification

时下流行的web service构建工具通常都不会照单全收,它们或多或少的只支持其中的一到两种,当然必不可少的还是:Request-Response

 

示例:

<wsdl:portType name="RulePortType">

<wsdl:operation name="underWriting">

  <wsdl:input name="underWritingRequest" message="tns:underWritingRequest" />

   wsdl:output name="underWritingResponse" message="tns:underWritingResponse" />

 </wsdl:operation>

</wsdl:portType>

 

 

绑定

 

Binding就是使WSDL包含的抽象信息开始变得具体的地方。它包含了具体的协议信息,这些信息可以通过可扩展元素来传播。其中SOAP作为一个可选的协议可以被应用在<binding>这个部分。如果采用SOAP那么还需要确定就包括:

Ø         SOAP消息将要使用的传输协议

Ø         操作的风格

Ø         操作的编码用法

Ø         SOAPAction

<wsdl:binding name="RuleHttpBinding" type="tns:RulePortType">

    <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

<wsdl:operation name="underWriting">

           <wsdlsoap:operation soapAction="" />

<wsdl:input name="underWritingRequest">

                     <wsdlsoap:body use="literal" />

             </wsdl:input>

<wsdl:output name="underWritingResponse">

  <wsdlsoap:body use="literal" />

  </wsdl:output>

      </wsdl:operation>

 </wsdl:binding>

服务

 

在这一部分,端口子元素<port>定义了服务的实际端点。

 

<wsdl:service name="Rule">

<wsdl:port name="RuleHttpPort" binding="tns:RuleHttpBinding">

          <wsdlsoap:address location="http://localhost:8088/BanCaWS/service/RuleEngine" />

     </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

 

至此我们简单的浏览了WSDL文档的结构并了解了其原则和抽象性划分,与SOAPHTTP的关系。在接下来的部分,我们会谈到更多关于Web Service工具以及部署的一些话题。

posted on 2006-10-13 11:32  SilenceCliff  阅读(728)  评论(1)    收藏  举报