知道美河 | 上传资料 | VIP申请 | 精品课程 | 资料搜索 | 问题反馈 | 会员手册 | 积分消费 | 积分充值 | 帐号保护
美河学习学习在线赞助VIP

美河学习在线(主站) eimhe.com

 找回密码
 建立账号
查看: 14831|回复: 18

[原创] WSDL文档(本人亲写 接之前的SOAP文档)

[复制链接]
发表于 2007-8-29 10:16:51 | 显示全部楼层 |阅读模式
此文档是工作需要编写 请务转载 如果你需要 可以声明或注明作者。。
我尽量做到一个知识点一个简短的例子 希望大家一起进步。
此文档是接前几天我发的SOAP文档。 我建议你现看看SOAP的文档 里面解释了大量专业术语和一些相关组织。。

对于SOA 和一些新的概念 如果大家有时间可以去我的雅虎博客看看
http://i.cn.yahoo.com/xt19833

[ 本帖最后由 xt19833 于 2007-8-30 10:45 编辑 ]
 楼主| 发表于 2007-8-29 10:25:33 | 显示全部楼层
WSDL

WSDL的产生】

为了在具体的web服务中使用SOAP,需要事先知道如何构造SOAP消息,要采用哪一种通讯协议(如HTTPSMTP)以及Web服务的Internet地址。总而言之,需要使用文档。
比如我们在SOAP文档里写到的BookQuoteSOAP消息非常简单,如1-1例:
<?xml version = “1.0” encoding= “UTF-8”>
<sopa:Envelope
Xmlns:soap=Http://schemas.xmlsoap.org/soap/envelope/
Xmlns:mh=”Http://www.Monson-Haefel.com/jwsbook/BookQuote”>

<soap:Body>


<mh:getBookPrice>


<isbn>0930849028</isbn>


</mh:betBookPrice>


</soap:Body>

</soap:Envelope>
虽然这个上个文档介绍的BookQuote Web服务的描述非常易于理解,但它并不是结构良好的文档,如果所有的Web服务都以这种方式描述,那么每当用户希望使用一个新的Web服务时,就需要读一个非正规的文档了。为了避免出现非正规文档的问题,Web服务社团采用了WSDL(Web Services Description Language,Web服务描述语言)WSDL是一个用于精确描述Web服务的文档格式。
WSDL的作用】---------------------------------------------------------------------------------------------

Wsdl
用来指定客户与具体的Web服务通信时必须使用的确切的消息格式,Internet协议以及地址。换句话说,WSDL文档要告诉用户如何使用Web服务。WsdlWeb服务的另外一个事实标准,而且像SOAP一样,它得到了广泛的认可,现在基本上所有的厂商都支持WSDL


WSDL
非常合适做代码生成器,它能够读WSDL文档,并可以访问Web服务生成一个程序化的接口。比如,JAX-RPC提供者要用WSDL1.1生成Java RMI 接口和网络占位程序,他们可用于与Web服务交换SOAP消息。


JAX-RPC
提供者是JAX-RPC API的一个供应商实现。比如,BEA WebLogic是一个JAX-RPC提供者。所有的J2EE1.4应用程序服务器是JAX-RPC提供者,因为它们均提供他们自己的JAX-RPC API实现。

       虽然WSDL特别适合用作代码生成器,但当使用其他的Web服务工具和API时,WSDL也是非常有用。比如,许多的Web服务客户要使用SOAP API而不是使用生成的调用接口和占位程序。这些API通常要用像EnvelopeHeaderBodyFault这样的对象对SOAP消息的结构进行建模。【当用户使用SOAP API时,可以用Web服务的WSDL作为与那个Web服务交换SOAP消息的向导。】
       虽然人们把WSDL看成一个Web服务标准,但它其实并不简单,这可能是它的最大障碍,本人看了很多的内容,到现在还是没有完全理解,自己觉得WSDL的复杂性取决于其设计者的目的,即对没有与任何具体的协议,编程语言或操作系统有联系的Web服务创建一个IDLinterface definition language,接口定义语言)。还有顺便说一下,WSDL1.1并不是专门用于SOAP,可以用它描述没有基于SOAPWeb服务。
       模块化是WSDL的另一个设计目的。由于WSDL非常模块化,因此用户可以重复使用它的功能来描述多个Web服务。非常遗憾的是,我觉得这样使得初学者很难读懂WSDL文档。我希望大家能认真的读懂前面的基本概念,还要去理解前面写的SOAP文档和深入了解一下XML的东西,可是很多情况下,用户从不需要读写自己的WSDL文档,因此自己的J2EE平台通常会自动创建并处理这些文档。我想在这说一下的是,如果你真的想真正的了解J2EE web services 我建议大家别用市面上的那些软件。。毕竟以后你用JAX-RPC的时候你会摸不到头脑,因为你根本不清楚这些WSDL的内部构造是怎么样的。顶多你只能应用而已。
WSDL的基本结构】------------------------------------------------------------------------

WSDL
文档是一个遵循WSDL XML模式的XML文档。作为XML文档实例,如果要使WSDL文档有效且格式良好的话,应必须以正确的方式使用正确的元素(感觉是废话哇,可是你看完下面的介绍你就知道为什么我要强调这些了)。下面的部分将介绍WSDL的结构以及如何构造恰当描述Web服务的WSDL。虽然WSDL能够用于描述任何种类的Web(从理论说),但我会重点介绍基于SOAP且符合WS-I Basic Profile 1.0(对这个陌生的可以去看看我发布的SOAP消息的文档)的Web服务的WSDL文档。

       一个WSDL文档包括了7个重要元素,即 typesimportmessageporttypeoperationbindingservices。这些元素嵌套于definitions元素中。Definitions元素是WSDL的根元素。来看看下面的表吧:
元素名称

元素作用

Types
使用了XML模式语言声明在WSDL文档中的其他位置使用的复杂数据类型与元素。
Import
类似于XML模式文档中的import元素,用于其他WSDL文档中导入WSDL定义
Message
使用在WSDL文档的type元素中定义或在import元素引用的外部WSDL文档中定义的XML模式内置类型,复杂类型或元素描述了消息的有效负载。
Porttype
operation元素描述了web服务的接口并定义了它的方法。Porttype元素及其operation元素类似于java接口和它的方法声明。
Operation
需要定义多个或一个message类型来定义它的输入和输出有效负载。
Binding
此元素将porttype元素及其operation元素赋给一个特殊协议(如SOAP1.1)和编码样式。
Services
此元素负责将一个internet地址赋给一个具体的绑定。
Documentation
此元素向读者说明了WSDL文档方面的一些信息,其他任何WSDL元素均可以包含documentation元素,documentation元素并不重要,我不会继续介绍了。

看看下面的1-2例子是一个非常简单的WSDL文档实例,该文档描述了前面SOAP里的BookQuoteWeb服务,当大家读到这里时,要记住它要描述一个Web服务以及用于访问该Web服务的SOAP消息类型,协议和Internet地址的类型:
示例1-2
<?xml version = “1.0” encoding= “UTF-8”>
<definitions name = “BookQuoteWS”
targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>

<!—消息元素(message)描述了输入和输出的参数-->
<message name = “GetBookPriceRequest”>

<part name = “isnb” type = “xsd:string”>

</messgae>

<message name = “GetBookPriceResponse”>

<part name = “price” type = “xsd:float”>

</messgae>

<!—portType 元素描述了web services 的抽象接口-->
<portType name = “BookQuote”>

<operation name = “getBookPrice”>


<input name = “isbn” message = “mh:GetBookPriceRequest”/>


<output name = “price” message = “mh:GetBookPriceRespsonse”/>


</operation>

</portType>

<!—binding 告诉了我们哪些协议和内码样式被使用-->

<binding name = “BookPrice Binding” type = “mh:BookQuote”>

<soapbind:binding style = “rpc”

Transport = http://schemas.xmlsoap.org/soap/http/>
<operation name = “getBookPrice”>

<soapbind: operation styles = “rpc”

Soap:Action =
http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice/>
<input>

<soapbind.body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</input>


<output>


<soapbind:body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</output>


</operation>


</binding>


<!—services 告诉我们Web ServicesInternet地址-->

<services name = “BookPriceServices”>

<port name = “BookPrice_port” binding = “mh:BookPrice_Binding”>


<soapbind:address location =

http://www.Monson-Haefel.com/jwsbook/BookQuote />

</port>

</services>
</definitions>

也许大家读到这里有点晕了吧。。。正常,不要泄气,这是初学WSDL的正常表现。在后面会对1-2例里出现的元素与属性作用,详细分解。

WSDL声明:definitions元素,types元素和import元素】
definitions元素详解】----------------------------------------------------------------------
所有WSDL文档的根元素均是definitions元素。该元素封装了整个文档,同时还通过它的名称提供了一个WSDL文档。
<definitions name = “BookQuoteWS”
targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>
definitions元素通常包含了若干个XML命名空间声明,这妒意根元素来说是正常的。这些声明中包括一个用于WSDL1.1XML模式的命名空间 http://schemas.xmlsoap.org/wsd/的声明。将WSDL命名空间声明为默认命名空间,就不再需要前缀来显示限定每一个WSDL元素了。

Definitions
元素中的第一个属性是name,该属性用来命名整个WSDL文档。其实整个属性不是那么重要,因为根本无任何对象要引用它。


Definitions
元素还定义了一个targetNamespace属性,该属性指定了WSDL文档中定义的命名空间,就像XMK模式文档中指定命名空间一样。


Message
portTypebinding元素利用他们的name属性指定了标签。这些标签会自动使用由targetNamespace属性指定的命名空间(这些例子还使用了targetnamespace属性赋给了URI的前缀mh)。标签的messageportTypebinding元素通常成为定义。这些定义假设了由targetnamespace属性指定的命名空间。

       文档中的其他元素用他们的标签和命名空间前缀引用定义。通常将带有前缀的标签看成是一个定义的完全限定名称。例如,下面的1-3例子中,inputoutput元素要用它们的限定名称引用消息定义。
<message name = “GetBookPriceRequest”>

<part name = “isnb” type = “xsd:string”>

</messgae>

<message name = “GetBookPriceResponse”>

<part name = “price” type = “xsd:float”>

</messgae>

<!—portType 元素描述了web services 的抽象接口-->
<portType name = “BookQuote”>

<operation name = “getBookPrice”>


<input name = “isbn” message = “mh:GetBookPriceRequest”/>


<output name = “price” message = “mh:GetBookPriceRespsonse”/>


</operation>

</portType>
types元素详解】-----------------------------------------------------------------------------------------

WSDL
采用了W3C XML模式内置类型(我们常理解为基本类型)。Type元素用作一个容器,用于定义XML模式内置类型(即复杂类型和定制的简单类型)中没有描述的各种数据类型。当声明消息部分(即有效负载)时,消息定义使用了在types元素中定义的数据类型与元素。

       下面的1-4例子没有使用types元素,我觉得不需要。直接的消息定义getBookPriceRequestgetBookPriceResponse引用了简单的内置数据类型。
       如果愿意,可以为ISBN号定义定制的简单类型,并在GetBookPriceRequest消息中使用该类型而不是内置String类型,让我们来看看实例1-4:

<definitions name = “BookQuoteWS”

targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>

<types>


<xsd:schema

targetNamespace = “http://www.Monson-Haefel.com/jwsbook/BookQuote”>
<!—这是ISBN的简单类型-->
<xsd:simpleType name = “ISBN”>

<xsd:restriction base = “xsd:string”>


<xsd:pattern value = “[0-9]{9}[0-9Xx]”>


</xsd:restriction>


</xsd:simpleType>


</xsd:schema>


</types>

<message name = “GetBookPriceRequest”>

<part name = “isnb” type = “mh:ISBN”>

</messgae>

<message name = “GetBookPriceResponse”>

<part name = “price” type = “xsd:float”>

</messgae>
……………………………………………..
</definitions>

在这里1-4例子中,types元素中直接嵌套了一个完成的W3C XML模式文档。实例1-4还定义了定制的简单类型(标签ISBN),并通过XML模式targetnamespace属性将其赋给了mh命名空间,然后用mhISBN类型定义了GetBookPriceRequest消息定义的isbn部分。

XML
模式的targetnamespace属性必须是一个有效的非空值,否则该类型个元素不属于一个有效的命名空间。此外,在types元素中定义的XML模式必须属于一个由WSDL文档(通常位于definitions元素中)指定的命名空间,或属于一个导入的WSDL文档的命名空间。换句话说,WSDL文档必须知道文档使用的各个命名空间。

【特别补充】------------------------------------------------------------------------------------------------

SOAP
WSDL均定义了属性与编码类型,用户可以用它们定义数组数据类型。但是这些数组类型和属性引起了混乱,并引起互操作性方面的问题,所以BP严格禁止使用他们。简单地说,不允许使用为SOAP1.1编码定义的Array类型或arrayType属性,也不允许使用由WSDL定义的WSDL arrayType属性。此外,用户不能将数组类型标记为WSDL1.1注释建议的ArrayOfxxxx形式。这些要求并不是障碍,因为XML模式提供了用于定义数组的更加容易的方式。

       定义数组时用户需要做的工作是用大于0maxOccurs属性加值(如10222222unbounded定义)定义一个复杂类型。而且用户还有其自己的基本数组如下例1-5

<definitions name = “BookQuoteWS”

targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>

<types>


<xsd:schema

targetNamespace = “http://www.Monson-Haefel.com/jwsbook/BookQuote”>
<!—这是简单的类似数组的类型-->
<xsd:simpleType name = “ISBN”>


<xsd:element name = “arg” type = “xsd:int” maxOccurs = “unbounded”>


</xsd:simpleType>


</xsd:schema>


</types>


import元素】----------------------------------------------------------------------------------------------
Import元素使得可以在当前WSDL文档中使用在其他WSDL文档中指定的命名空间中的定义有效。如果用户希望模块化WSDL文档(如为了将抽象定义(typesmessageporttype元素)与具体定义(bindingservicesport元素)相区分),则此功能非常有用。
       使用import元素的另一个原因是,将若干个想要单独维护的定义放在一个WSDL文档中,但要在可由商业伙伴访问的公共目录中对所有Web服务提供一个完整的定义。让我们看看下面的1-6例子吧:
<definitions name = “AllMhWebServices”
Xmlns=http://schemas.xmlsoap.org/wsdl/ >
<import namespace = http://www.Monson-Haefel.com/jwsbook/BookQutoe
Location = “http://www.Monson-Haefel.com/jwsbook/BookPrice.wsdl”>

<import namespace = http://www.Monson-Haefel.com/jwsbook/Po
Location = “http://www.Monson-Haefel.com/jwsbook/wsdl/PurchaseOrder.wsdl”>

<import namespace = http://www.Monson-Haefel.com/jwsbook/Shipping
Location = “http://www.Monson-Haefel.com/jwsbook/wsdl/Shipping.wsdl”>

</definitions>

WSDL
import元素必须声明2个属性,即namespace属性和location属性。Namespace属性的值必须与正导入的WSDL文档中声明的targetnamespace相匹配,location属性必须指向一个实际的WSDL文档,不能为空。

       有人将location属性看成一条线索。如果读WSDL文档的应用程序在本地缓存或储存了所导入的WSDL文档的复制,那么location属性有可能要使用他们。
【特别注意】-----------------------------------------------------------------------------------------------------

Import
元素的使用很容易,但它也会引起版本匹配问题。如果WSDL文档是单独维护的,那么就非常有可能出现导入的文档发生更改(希望这里大家好好想想为什么),但没有考虑导入它的WSDL文档的现象。要保证在更改导入的WSDL文档时考虑版本问题。

----------------------------------------------------------------------------------------------------------------------

       用户可以使用import元素和types元素,但应该在WSDL文档的types元素之前列出import元素。
       WSDLimport元素的目的而言有许多的混乱。有些人认为应该用该元素导入WSDL文档或导入XML模式文档,而有些人则认为它只适用于导入WSDL文档。不同的解释引起了互操作性问题。因此,BP规定WSDLimport元素能能引用WSDL文档。如果用户用户需要导入一个XML模式元素,则应该在WSDL type元素内包含的模式定义中导入。【需要注意的是 用户不能用XML模式的import语句直接从其他一些WSDL文档的types元素中导入一个XML模式】
WSDL抽象接口:message元素,portType元素和operation元素】-----------------------------------

Message
portTypeoperation元素均用于描述Web服务的抽象接口。portType元素将operation定义和message定义组合成一个与java的接口定义类似的抽象接口。portType元素描述了Web服务所支持的操作种类(即消息传递模式和有效负载),但没有指定所用的Internet协议或地址。

message元素】-------------------------------------------------------------------------------------------------

Message
元素描述了Web服务使用的消息的有效负载。Message元素可以描述输出或接收消息的有效负载,即直接发送到Web服务或直接从Web服务接收到的消息。此外,message元素可以描述SOAP文件头和错误detail元素的内容。定义message元素的方式取决于用户使用RPC模式或者是文档样式的消息传递模式。
 楼主| 发表于 2007-8-29 10:28:03 | 显示全部楼层
【用于RPC样式Web服务的message元素】------------------------------------------------------
       当使用RPC样式的消息传递时,message元素描述了SOAP请求和应答消息的有效负载。这些元素可以描述调用参数,调用返回值,文件头以及错误。比如,SOAP文档中的BookQuote Web服务用2message元素来描述该服务的参数与返回值(以后在介绍如何用消息描述错误和文件头)下面1-7例子:
<message name = “GetBookPriceRequest”>

<part name = “isnb” type = “xsd:string”>

</messgae>

<message name = “GetBookPriceResponse”>

<part name = “price” type = “xsd:float”>

</messgae>


GetBookPriceRequest
消息表示参数(即输入),GetBookPriceResponse表示应答(即输出)。换句话说,GetBookPriceRequest消息藐视了从SOAP客户向BookQuote Web服务所传递的消息的有效负载,而GetBookPriceResponse消息描述了由BookQuote Web服务传递回客户的有效负载。

       其实命名消息并没有规定习惯,在我这次写的文档中,从SOAP客户传递给服务器的消息附加有后缀Request,而传递回客户的消息则附加后缀Response。大家可以采用自己的命名习惯,就是说消息名称可以是任何名称,它不过是用来标识消息定义的而已。消息元素不能将其本身声明为输入或输出(我想在operation元素中在具体加以区分吧),因此消息命名成requestresponse并不能确定如何使用这些消息。
       RPC样式的消息中,消息通常分为多个部分。比如,可以用多个part元素定义一个名为GetBookPriceRequest的消息,其中每个元素表示不同的参数,如下 1-8例:
<message name = “GetBookPriceRequest”>

<part name = “isnb” type = “xsd:string”>


<part name = “quantity” type = “xsd:int” >

</messgae>

<message name = “GetBookPriceResponse”>

<part name = “price” type = “xsd:float”>

</messgae>
Web服务中的输入和输出均可以有多个部分,这一点与Java方法调用语义不同,后者允许多个参数输入,但只有一个输出(看成返回值)。然而,对于像C++C#Perl等这样的编程语言来说,更常见的情况是它们声明的参数即可以是输入参数,也可以是输出参数。

Wsdl
是一个中性编程语言,所以它必须有足够的灵活性,从而与所有编程语言相兼容,而不是为了某个语言。SAAJJAX-RPC均具有用多个部分支持输出消息的功能。

【文档样式Web服务的message元素】------------------------------------------------------------------
       当用户采用文档样式消息传递模式时,message元素定义要引用types定义中的顶级元素。如下例1-9:描述一个SubmitPurchasePrder Web ServicesWSDL文档,PO命名空间是以前SOAP文档中的。此例是单向消息传递模式,所以没有应答,这在文档样式中是最常见的了。

<definitions name = “SubmitPurchasePrder”

targetNamespace = http://www.Monson-Haefel.com/jwsbook/PO
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/PO
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>

<types>



<xsd:schema

targetNamespace = “http://www.Monson-Haefel.com/jwsbook/PO”>
<!—导入这个SubmitPurchasePrder XML 规则文档-->
<xsd:import namespace = http://www.Monson-Haefel.com/jwsbook/PO
schemaLocation = http://www.Monson-Haefel.com/jwsbook/po.xsd />



</xsd:schema>



</types>

<message name = “SubmitPurchasePrderMessage”>

<part name = “isnb” element = “mh: purchasePrder”>

</messgae>
……………………………………………..
</definitions>
       消息部分可以声明type属性或者element属性,但不能同时声明两者。具体声明哪一种属性取决于传递消息的种类。如果用户使用的是RPC样式的消息传递,那么part元素必须使用type属性:如果用户使用的是文档样式的消息传递,part元素则必须是element属性。RPC样式的消息传递用类型来定义过程调用,该调用中每个元素表示某一类型的参数。此外,文档样式的消息传递要交换XML文档段,并引用它们的顶级元素(即全局元素)。

【声明错误消息】-----------------------------------------------------------------------------------------------
       用户可以用消息定义声明错误,其声明方式与用消息等译声明输入和输出消息的方式相同。比如下面程序2-1定义了一个错误消息,如果BookQuote请求消息包含了一个无效的ISBN,则会将该错误消息返回。它就包含一个部分,就是错误消息。

<definitions name = “BookQuote”

targetNamespace = http://www.Monson-Haefel.com/jwsbook/PO
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/PO
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>


<types>


<xsd:schema


<xsd:element name = “InvalidIsbnFaultDetail”>


<xsd:complexType>


<xsd:sequence>



<xsd:element name = “offending-value” type = “xsd:string” />



<xsd:element name = “conformance-rules” type = “xsd:string” />


</xsd:sequence>


</xsd:complexType>


<xsd:element>


</xsd:schema>


</types>

<message name = “SubmitPurchasePrderMessage”>

<part name = “isnb” element = “mh: purchasePrder”>

</messgae>

<message name = “InvalidArgumentFault”>

<part name = “error_message” element = “mh: InvalidArgumentFault” />

</messgae>

……………………………………………..
</definitions>

portType元素】-----------------------------------极为重点-----------------------------------------------

portType
元素定义了Web服务的抽象接口。从概念上讲,该接口有点像java接口,因为它定义了一个抽象类型和它的方法,但没有定义实现。在WSDL中,portType元素是由binding元素和services元素实现的,这两个元素用于说明Web服务实现使用的Internet协议,编码方案以及Internet地址。


portType
元素的“方法”是它的operation元素。portType元素可以有一个或多个operation,其中每个operation元素定义了一个RPC样式或文档样式Web服务方法。每个operation元素最多是由一个inputoutput元素以及任意数量的fault元素组成。

       在下面的2-2例子中名为“BookQuote”的portType元素(左列)声明了三个操作,即GetBookPriceGetBulkBookPriceGetBookIsbn。右为对应的Java接口。如下例:


WSDL portType定义

Java接口

<portType name = “BookQuote”>
<operation name = “GetBeokPrice”>

<input name = “isbn”

Public interface BookQuote{

Public float getBookPrice


(String isbn);


Message = “mh:GetBookPriceRequest”/>

<output name = “price”

Message = “mh:GetBookPriceResponse” />
</operation>
<!----------------------------------------------->

<operation name = “GetBulkBoekPrice”>

<input name = “request”

Message = “mh: GetBulkBoekPrice”/>

<output name = “price”

Message = “mh: GetBulkBoekPrice” />
</operation>

<!----------------------------------------------->
<operation name = “GetBookIsbn”>

<input name = “title”

Message = “mh: GetBookIsbn Request”/>

<output name = “price”

Message = “mh: GetBookIsbn Response” />
</operation>









Public float getBulkBoekPrice

(String isbn,int quantity);







Public String getBookIsbn(String bookTitle);
WSDL,portTypejava接口并不完全相同,但它们非常接近。其实,大多数给予javaWeb服务代码生成器均在java接口和WSDL portType元素之间创建了映射。它们其实是根据WSDLportType元素生成java接口,而且也可以根据简单的Java接口生成portType元素,operation元素和message元素。
WSDL文档可以有一个或多个portType元素,其中每个portType元素描述了不同Web服务的抽象接口,比如:一个WSDL Web服务可以定义一个名为BookQuotePortType元素和一个名为SubmitpurchaseOrderportType元素。
 楼主| 发表于 2007-8-29 10:30:11 | 显示全部楼层
operation元素】------------------------------------------------------------------------------------------------
       portType元素声明的每一个operation元素要用一个或多个消息定义来定义、它的输入、输出已经错误。在2-3例子中,BookQuote portType元素将GetBookPriceRequest声明为它的input元素、将GetBookPriceRsponse声明为它的output元素、并将InvalidArgumentFault声明为它的fault元素。

<portType name = “BookQuote”>



<operation name = “getBookPrice”>


<input name = “isbn” message = “mh:GetBookPriceRequest”/>


<output name = “price” message = “mh:GetBookPriceRsponse”/>


<fault name =“InvalidArgumentFault” message = “mh: InvalidArgumentFault”>


</operation>


</portType>



Input
消息表示传递到Web服务的有效负载,output消息则表示传递到客户的有效负载。在RPC样式的消息传递中input是请求,output是客户。而在文档样式的消息传递中,input是传递到Web服务的XML文档段,output是传递回客户的XML文档段。除input消息和output消息外,一个错做可以不包含fault错误消息或包含多个fault错误消息,其中每个错误消息用于描述不同类型的错误。

1.0 操作的参数错误】-------------------------------------------------------------------------------------
       WSDL中,当使用RPC样式的消息传递时,要假设客户使用的是过程调用语义,比如:JAX-RPC使用带方法调用的Java RMI接口对基于SOAPRPC样式的Web服务建立模型。很多情况下,必须按制定的顺序传输inputoutput消息的参数,其顺序与过程调用时所使用的参数顺序要完全相同。为了使inputoutput消息参数采用正确的顺序,operation元素可以声明一个parameterOrder属性。如2-4例一个名为“GetBulkBookPrice”的操作用parameterOrder属性来指定其输入和输出的参数是顺序。
<message name = “GetBulkBookPriceRequest”>

<part name = “isnb” type = “xsd:string”>


<part name = “quantity” type = “xsd:int” >

</messgae>

<message name = “GetBulkBookPriceResponse”>

<part name = “prices” type = “mh:pricet”>

</messgae>

<portType name = “GetBulkBookPrice”>

<operation name = “GetBulkBookPrice” parameterOrder = “isbn quantity”>


<input name = “isbn” message = “mh: GetBulkBookPriceRequest”/>


<output name = “price” message = “mh: GetBulkBookPriceRsponse”/>




</operation>


</portType>

使用ParameterOrder属性时,该属性必须包含所有输入部分,并且只包含不是返回类型的输出部分。因此,如果一个output只有一个部分(不如上面的2-4例子),那么会假设它只有一个返回值,故不应该列在ParameterOrder属性中。
如果ParameterOrder属性列出了output部分,那么会将它按OUT参数对待。当portType元素中的inputoutput元素用相同的名称声明了一个部分时,该部分是一个INOUT参数。而且在inputoutput元素中的类型必须相同。
ParameterOrder属性含义的不同解释会引起一些互操作性问题。Basic Profile通过提供单一的ParameterOrder属性解决了问题。从发送方向接收传递的参数顺序必须符合input消息定义和output消息定义中的part声明的顺序。
ParameterOrder属性的目的是说明哪些部分是返回类型。
ParameterOrder属性提供的列表中忽略的任何部分均假设为操作的返回类型。过程调用可以只有一个返回类型,因此只能从ParameterOrder属性中忽略一个输出部分。
2.0操作重载】
       这里我不多说这个问题,因为这个会引起极大的互操作问题。因此BP禁止操作重载。
portType元素定义的每个操作必须有唯一的名称,但允许2个或多个portType元素用完全相同的名称声明操作元素,因为每个portType被认为是一个单独定义。
WSDL消息传递交换模式】------------------------------------------------------------------------------

Web
服务中使用四种基本的消息交换模式(简称MEP),即请求/响应、单向、通知、以及恳求/响应模式。

       虽然WSDL支持通知和恳求/响应消息传递模式,但BP不支持它们。而且实际上用的很少。目前,大多数基于WSDLWeb服务使用请求/响应消息传递模式或单向消息传递模式,而且它们是能与J2EE Web Services 一起使用的MEP

WSDL
文档可以通过声明它的输入和输出元素来为一个具体的操作确定MEP。看下面的1-1图吧。说明了请求/响应消息传递模式或单向消息传递模式的区别。



1.0请求/响应消息传递】-------------------------------------------------------------------------------------
       在请求/响应消息传递中,客户通过向Web服务发送请求消息来启动通信,而且Web服务要用响应消息来应答。
       如果用一个input元素和一个output元素(output元素位于input元素之后)声明operation,那么它会定义一个请求/响应操作。通过首先列出input元素,operation表示Web服务接收到最初由客户发送的消息:将output元素列在input元素之后,则表示Web服务对消息给于响应,下面2-5例子,表示一个只使用一个input和一个output元素的经典请求/响应模式。
<portType name = “GetBulkBookPrice”>

<operation name = “GetBulkBookPrice” >


<input name = “isbn” message = “mh: GetBulkBookPriceRequest”/>


<output name = “price” message = “mh: GetBulkBookPriceRsponse”/>




</operation>

</portType>
       请求/响应操作除了使用一个input元素和一个output元素外,还可以包含多个fault元素。Fault元素要在错误事件中返回给客户。(个人建议弄清客户的含义)请求/响应操作可以没有错误或有多个错误,如下2-6:
<portType name = “GetBulkBookPrice”>

<operation name = “GetBulkBookPrice” >


<input name = “isbn” message = “mh: GetBulkBookPriceRequest”/>


<output name = “price” message = “mh: GetBulkBookPriceRsponse”/>


<fault name =“InvalidArgumentFault” message = “mh: InvalidArgumentFault”>


<fault name =“SecurityFault” message = “mh: SecurityFault”>




</operation>

</portType>
2.0单向消息传递】--------------------------------------------------------------------------------------------
       在单向消息传递中,客户将消息传递给Web服务,但不期待应答。此MEP通常被认为是异步消息传递。
       单项消息传递是当今仅次于请求/响应消息传递的流行MEP
       如果用一个input但没有使用output声明了一个操作,那么就定义了一个单向操作。如果只列出了input消息,那么operation表示客户要把消息发送到Web服务,但不期待应答。下面2-7例子说明了一个简单的单向操作SubmitPuraseOrder PortType
<portType name = “SubmitPuraseOrder PortType”>

<operation name = “SubmitPuraseOrder” >


<input name = “isbn” message = “mh: SubmitPuraseOrderMessage”/>


</operation>

</portType>
       单向操作与请求/响应操作不同。单向操作不可以指定错误,也不需要生成错误消息。单向消息传递模式是严格但方向的,不能把错误传递回客户。
【通知和恳求/响应消息传递】----------------------------------------------------------------------------

J2EE Web Services
中不能使用通知和恳求/响应MEPJ2EE Web Services 之所以不支持他们,其原因是因为WSDL1.1规范不能很好的标识他们。而且它们带来的问题比它们所解决的问题还要多,但我们可以理解~~呵呵。

       在通知消息传递中,Web服务将消息发送给客户,但并不期望应答消息。使用通知MEPWeb服务符合分布计算的推模式(Push model 不能理解的可以去百度里搜),假设客户向Web服务进行了注册,以便接收有关一个事件的消息(看成通知)。通过注册来接收通知的客户称为订阅者(Subscriber)。在通知消息传递中,portType包含一个output元素,但不包含input消息定义。
       恳求/响应类似于通知,但客户要期待对Web服务的响应。与通知消息传递一样,恳求/响应Web服务的客户必须订阅服务以便接收消息。在该MEP里,portType元素首先要声明output消息,然后才是input消息。顺序相反。
 楼主| 发表于 2007-8-29 10:32:16 | 显示全部楼层
----------------------------------------------------------------------------------------------------------------------
这里是WSDL文档的一个段落

----------------------------------------------------------------------------------------------------------------------
WSDL实现:binding元素】

Binding
元素将一个抽象portType映射到一组具体协议(如SOAPHTTP)、消息传递模式(RPC或文档)以及编码样式(字面或SOAP编码)。


Binding
元素及其子元素与协议专用的元素组合在一起使用。Binding元素确定出正在绑定的portType元素和operation元素、而协议专用的元素声明与portType关联的协议与编码样式。

       每种类型的协议(如果SOAPHTTPMIME)有其自己的一组协议专用元素和其自己的命名空间。如下3-1例声明了将BookQuote portType绑定到使用SOAP专用协议元素的SOAP1.1协议。。。

<?xml version = “1.0” encoding= “UTF-8”>

<definitions name = “BookQuoteWS”
targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl>

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

<!—binding 告诉了我们哪些协议和内码样式被使用-->

<binding name = “BookPrice Binding” type = “mh:BookQuote”>

<soapbind:binding style = “rpc”

Transport = http://schemas.xmlsoap.org/soap/http/>
<operation name = “getBookPrice”>

<soapbind: operation styles = “rpc”

Soap:Action =
http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice/>
<input>

<soapbind.body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</input>


<output>


<soapbind:body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</output>


</operation>


</binding>

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
</definitions>
       我向大家要注意的第一个问题是此例中声明的binding元素实际上是由2个不同的命名空间组成的,没有命名空间前缀的元素是WSDL1.1命名空间http://schemas.xmlsoap.org/wsdl啊成员。此命名空间是WSDL文档的默认命名空间。WSDL1.1通用的绑定元素是bindingoperationinputoutput。另外,soapbindbindingsoapbindoperationsoapbindbody元素是协议专用的元素,它们是SOAP-WSDL绑定的命名空间http://schemas.xmlsoap.org/wsdl/soap的成员。在来看看3-2的实例:

<?xml version = “1.0” encoding= “UTF-8”>

<definitions name = “BookQuoteWS”
targetNamespace = http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:mh=http://www.Monson-Haefel.com/jwsbook/BookQuote
xmlns:soapbind=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:xsd=http://www.w3.org/2001/XMLScheam
xmlns=”http://schemas.xmlsopa.org/wsdl”>

<!—binding 告诉了我们哪些协议和内码样式被使用-->

<binding name = “BookPrice Binding” type = “mh:BookQuote”>

<soapbind:binding style = “rpc”

Transport = http://schemas.xmlsoap.org/soap/http/>
<operation name = “getBookPrice”>

<soapbind: operation styles = “rpc”

Soap:Action =
http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice/>
<input>

<soapbind.body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</input>


<output>


<soapbind:body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</output>


</operation>


</binding>

</definitions>

Soapbind:binding
元素和soapbind:body元素用于表示Web服务的SOAP专用细节,比如:soapbind:binding说明了消息样式是RPC,并且网络应用协议是HTTPSoapbind:body元素说明了输入和输出均使用了字面编码。后面会详细接触到SOAP绑定元素。


Binding
元素的子元素(operationinputoutput元素)可以直接映射到portType元素的子元素。如下3-3

<portType name = “BookQuote”>

<operation name = “
getBookPrice”>


<
input name = “isbn” message = “mh:GetBookPriceRequest” />


<
output name = “price” message = “mh:GetBookPriceRsponse” />


</operation>

</portType>

<binding name = “BookPrice Binding” type = “mh:BookQuote”>
<soapbind:binding style = “rpc”
Transport = http://schemas.xmlsoap.org/soap/http
/>

<operation name = “getBookPrice”>

<soapbind: operation styles = “rpc”

Soap:Action =
http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice/>
<input>

<soapbind.body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</input>


<
output>


<soapbind:body use = “literal”

Namespace = http://www.Monson-Haefel.com/jwsbook/BookQuote />

</output>


</operation>

</binding>
====================================================================
portType元素的name属性对应着binding元素的 type属性。
portType元素中的operation元素的 name属性对应着binding元素中的operation元素中的name属性
portType元素中的operation元素的inputoutput元素分别与binding元素中的operation元素中的inputoutput属性对应。
====================================================================
       虽然到目前为止给出的绑定示例均使用SOAP绑定元素,但WSDL规范上实际还是为HTTPMIME定义了其他两个协议专用绑定。如下3-4
<!—HTTP/MIME-binding of BookQuote-->
<binding name = “BookPrice_HttpMimeBinding” type = “mh:BookQuote”>

<Http:binding verb = “GET”>


<operation name = “getBookPrice”>


<http:operation location = “alt.http.service” />


<input>


<http:urlEncoded/>


</input>


<output>


<mime:content type = “text/html”>


</output>


</operation>

</binding>
       虽然WSDL1.1允许使用MIME绑定和HTTP绑定(如上例),但Basic Profile不允许使用这两种绑定,因为他们的文档结构很差。
       此限制只适合BP1.0 WS-I已声明它将下一个版本的Basic Profile中扩展对SwA的支持。其中包括WSDL MIME绑定。
 楼主| 发表于 2007-8-29 10:34:23 | 显示全部楼层
发表于 2007-8-29 10:47:48 | 显示全部楼层
发表于 2007-8-29 11:03:02 | 显示全部楼层
发表于 2007-8-29 13:41:26 | 显示全部楼层
发表于 2007-8-29 14:38:55 | 显示全部楼层
 楼主| 发表于 2007-8-30 10:44:08 | 显示全部楼层
普元公司已经真正的拥有了基于SOA思想构架的系统开发工具了,
对于SUN 来说 SUN JAVA Composite Appliction PlatForm Suite Primer工具 将是未来软件开发的转折点。。
而这些一切的一切都是基于 J2EE JAVA Web Services 的东西
本人基于SOA工作快一年了有着深刻的体会  只是希望大家看事别那么狭隘 多关心一下市场的发展 毕竟现在的社会需要的灵活性的战略 而不是一味的执着了。
 楼主| 发表于 2007-9-2 10:06:42 | 显示全部楼层
发表于 2007-9-6 23:40:41 | 显示全部楼层
发表于 2007-9-8 06:41:25 | 显示全部楼层
MY GOD!!你写的究竟是什么?看不懂啊。看来还得多学习了!
 楼主| 发表于 2007-9-8 21:09:46 | 显示全部楼层
楼上的朋友..
很抱歉~~不能给你提供相关的帮助~很多事情
不过我可以给你2个希望对你有帮助的网址 希望能帮助你
http://bbs.w3china.org/dispbbs.asp?boardID=10&ID=46105

http://bjzhanghao.cnblogs.com/archive/2005/06/12/173302.html

http://blog.hangzhou.com.cn/inde ... e_itemid_33796.html

如果你外语不错..详细的东西在提供你个地址
http://www.mindswap.org/2004/owl-s/api/
发表于 2007-11-12 11:56:36 | 显示全部楼层
很不错,以前看了一下,对一些概念一直有点模糊,通过看你的文章,总算都弄懂了,非常谢谢楼主
 楼主| 发表于 2008-1-20 15:53:30 | 显示全部楼层
发表于 2009-2-2 16:35:06 | 显示全部楼层
楼主,您好,我现在遇到一个问题,一直解决不了。
我用GSOAP和C头文件生成WSDL的时候,如果我用GSOAP2.3生成的WSDL没有问题,无论是在C环境还是在JAVA环境下都没有问题,但用GSOAP2.7生成的WSDL文件不能使用,提示错误,经过仔细分析,发现GSOAP2.7生成的WSDL时候,如果复杂数据类型作为输出参数的时候,在TYPES中就没有这个这个复杂数据的声明了,例如:我有一个这样的C接口int sam__mes_CreateUser(
    struct sam__ClientInfo *stClientInfo,
    struct sam__TransactionInfo *stTransactionInfo,
    struct sam__mes_UserInfo *stUserInfo,
    struct sam__ErrorInfo * stErrorInfo);(gsoap规定最后一个参数为返回参数,即stErrorInfo为返回参数)

2.7生成WSDL的时候,在TYPES中就没有
  <complexType name="ErrorInfo">
   <sequence>
     <element name="ErrorCode" type="xsd:int" minOccurs="1" maxOccurs="1"/>
     <element name="ErrorMsg" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
   </sequence>
  </complexType>
这个声明了,如果sam__ErrorInfo不作为输出参数就可以输出这样的声明,我的C头文件有struct sam__ErrorInfo
{
    xsd__int ErrorCode;
    xsd__string ErrorMsg;   
};这样的声明,但好想GSOAP2.7就忽略了。搞了很久,不知道怎么办,因为我的C头文件不能更改,以前是用GSOAP2.3生成WSDL,现在想改为GSOAP2.7生成WSDL给客户端使用,但使用不了出错,提示也是说ErrorInfo没有声明。
发表于 2009-4-5 13:33:57 | 显示全部楼层
您需要登录后才可以回帖 登录 | 建立账号

本版积分规则

 
QQ在线咨询

QQ|小黑屋|手机版|Archiver|美河学习在线 ( 浙网备33020302000026号 )

GMT+8, 2025-5-2 18:30

Powered by Discuz!

© 2001-2025 eimhe.com.

快速回复 返回顶部 返回列表