WebService 之 WSDL文件 讲解
? ??? 恩,我想说的是,是不是经常有人在开发的时候,特别是和第三方有接口的时候,走的是SOAP协议,然后用户给你一个WSDL文件,说按照上面的进行适配,嘿嘿,这个时候,要是你以前没有开发过,肯定会傻眼,那如果你想学习的话,就认真的看下面的讲解咯: 一、WSDL概述 二、WSDL基本结构
???????? ?
<?
xml?version="1.0"?encoding="UTF-8"
?>
??????????? WSDL的声明必须定义成使用:UTF-8 或者UTF-16 编码。 ??????? 3.2 definition元素
<
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/XMLSchema" ???????????????????? xmlns ="http://schemas.xmlsoap.org/wsdl/" > ?definition元素中一般包括若干个XML命名空间; ?http://schemas.xmlsoap.org/wsdl/是默认的命名空间,这样就可以不用显式地定义每一个WSDL元素的命名空间了,例如: < types > ? < messages > ? < portType > …;文档中所有的元素缺省应该属于这个命名空间。 definition元素的的一个属性是name,此属性不重要可以没有; ? ?定义了targetNamespace命名空间,它为在模式中显式创建的所有新类型均声明了XML命名空间,而且上面的例子中赋予了mh前缀。 <!-- ?message?elements?describe?the?input?and?output?parameters? --> < message? name ="GetBookPriceRequest" > ???? ? < part? name ="isbn" ?type ="xsd:string" ? /> </ message > < message? name ="GetBookPriceResponse" > ???? < part? name ="price" ?type ="xsd:float" ? /> </ message > <!-- ?portType?element?describes?the?abstract?interface?of?a?Web?service? --> < portType? name ="BookQuote" > ??? < operation? name ="getBookPrice" > ????????? < input? name ="isbn" ?message ="mh:GetBookPriceRequest" /> ????????? < output? name ="price" ?message ="mh:GetBookPriceResponse" /> ?? </ operation > </ portType > ? ???????? 上面的例子中:message元素利用name属性指定了标签(例如:GetBookPriceRequest),这些标签会自动使用targetNamespace的命名空间,标签了的messages元素通常被称为定义。
<?
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/XMLSchema" ???????????????????? xmlns ="http://schemas.xmlsoap.org/wsdl/" > < types > ???? < xsd:schema?? targetNamespace ="http://www.Monson-Haefel.com/jwsbook/BookQuote" > ?????? <!-- ?The?ISBN?simple?type? --> ?????? < xsd:simpleType? name ="ISBN" > ???????? < xsd:restriction? base ="xsd:string" > ?????????? < xsd:pattern? value ="[0-9]{9}[0-9Xx]" ? /> ???????? </ xsd:restriction > ?????? </ xsd:simpleType > ???? </ xsd:schema > </ types > ???????? Types元素作为一个容器,用来定义XML模式内置的数据类型(即复杂类型和定制的简单类现,详细见Web Service XML文章)中没有描述的各种数据类型。例如:ISBN。
<
definitions?
name
="AllMhWebServices"
?????????xmlns ="http://schemas.xmlsoap.org/wsdl/" > ???? < import? namespace ="http://www.Monson-Haefel.com/jwsbook/BookQuote" ?????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元素必须声明两个属性,即namespace属性和location属性。
<
message?
name
="GetBulkBookPriceRequest"
>
???? < part? name ="isbn" ?type ="xsd:string" /> ???? < part? name ="quantity" ?type ="xsd:int" /> ?? </ message > ?? < message? name ="GetBulkBookPriceResponse" > ???? < part? name ="price" ?type ="mh:prices" ? /> ?? </ message > RPC式样的Web服务的message服务 GetBulkBookPriceRequest表示消息的输入(相当于函数的参数),GetBulkBookPriceResponse表示消息的输出(相当于函数的返回值) Web?Service的输入和输出参数可以是多个(一个特点),每一个输入或者输出使用part元素定义,RPC样式必须使用type来定义类型 RPC样式用类型来数据定义过程调用,调用中的每一个元素表示某一个类型的参数。 < types > ???? < xsd:schema? targetNamespace ="http://www.Monson-Haefel.com/jwsbook/PO" > ?????? <!-- ?Import?the?PurchaSEOrder?XML?schema?document? --> ?????? < xsd:import? namespace ="http://www.Monson-Haefel.com/jwsbook/PO" ???????schemaLocation ="http://www.Monson-Haefel.com/jwsbook/po.xsd" ? /> ???? </ xsd:schema > ?? </ types > ?? <!-- ?message?elements?describe?the?input?and?output?parameters? --> ?? < message? name ="SubmitPurchaSEOrderMessage" > ???? < part? name ="order" ?element ="mh:purchaSEOrder" ? /> ?? </ message > 文档式样Web服务的Messages元素: 当用户采用文档式样消息传递模式的时候,messages元素要应用types定义中的顶级元素。具体顶级元素的定义和XML?schema详见Web?Server?XML文档。 消息部分使用element属性定义 文档式样的消息传递要交换XML文档,并且应用它们的顶级元素。 注:Messages元素的RPC/Document试样对应了SOAP?RPC/Document消息传递模式,详细见Web?Server?SOAP相关文档 < types > ???? < xsd:schema? targetNamespace ="http://www.Monson-Haefel.com/jwsbook/PO" > ?????? <!-- ?Import?the?PurchaSEOrder?XML?schema?document? --> ?????? < 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?elements?describe?the?input?and?output?parameters? --> ?? < message? name ="GetBookPriceRequest" > ???? < part? name ="isbn" ?type ="xsd:string" ? /> ?? </ message > ?? < message? name ="GetBookPriceResponse" > ???? < part? name ="price" ?type ="xsd:float" ? /> ?? </ message > ?? < message? name ="InvalidArgumentFault" > ???? < part? name ="error_message" ?element ="mh:InvalidIsbnFaultDetail" ? /> ?? </ message > ? 声明错误消息: 错误使用的消息定义只能采用Document/Literal编码样式 上面声明了匿名类型,InvalidIsbnFaultDetail不需要type类型,complexType中也不包括name属性,详细见Web?Service?XML相关文档。
<
message?
name
="GetBulkBookPriceRequest"
>
?? < part? name ="isbn" ?type ="xsd:string" /> ?? < part? name ="quantity" ?type ="xsd:int" /> </ message > < message? name ="GetBulkBookPriceResponse" > ?? < part? name ="prices" ?type ="mh:prices" ? /> </ message > < message? name ="InvalidArgumentFault" > ???? < part? name ="error_message" ?element ="mh:InvalidIsbnFaultDetail" ? /> ?? </ message > < portType? name ="GetBulkBookPrice" ? > ?? < operation? name ="getBulkBookPrice" ?parameterOrder ="isbn?quantity" > ????? < input? name ="request" ?message ="mh:GetBulkBookPriceRequest" /> ????? < output? name ="prices" ?message ="mh:GetBulkBookPriceResponse" /> < fault? name ="InvalidArgumentFault" ?message ="mh:InvalidArgumentFault" /> ?? </ operation > </ portType > Input表示传递到Web服务的有效负载;output表示返回给客户的有效负载;可以不包括,也可以包括一个或者多个fault错误消息。 parameterOrder定义了input和output消息采用的正确的顺序 使用parameterOrder的时候,必须包含所有输入参数部分;并且只包含不是返回类型的输出部分,如果output只有一个part(上例),会假设返回值,所以不包括在parameterOrder中 如果parameterOrder列出output中的part部分,那么这个将被作为OUT参数,如果input元素和output元素使用相同的名称声明了一个部分的时候,此部分为INOUT参数 ??????? 4.4 WSDL消息交换模式(MEP)
<
binding?
name
="BookPrice_Binding"
?type
="mh:BookQuote"
>
?? < soapbind:binding? style ="rpc" ???transport ="http://schemas.xmlsoap.org/soap/http" /> ?? < operation? name ="getBookPrice" > soapbind:binding元素指定了用于传输SOAP消息的Internet协议以及operation缺省的消息类型(RPC还是文档类型) http://schemas.xmlsoap.org/soap/http表示采用的是HTTP的传输方式,当然也可以用HTTPS,用户具体使用HTTP还是HTTPS取决于Port元素中定义的location属性声明中的模式。 上面的rpc表示缺省状态下:operation将采用RPC的方式传递消息负载。 ???????? 5.2 soapbind:operation元素
<
operation?
name
="getBookPrice"
>
???? < soapbind:operation? style ="rpc" ?????soapAction = ?????"http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice" /> POST?1ed/BookQuote?HTTP/1.1 Host:?www.Monson-Haefel.com Content-Type:?text/xml;?charset="utf-8" Content-Length:?nnnn SOAPAction="http://www.Monson-Haefel.com/jwsbook/BookQuote/GetBookPrice" soapbind:operation元素指定了消息传递样式(RPC或者document),并且指定了SOAPAction字段的值。 上面的例子显示在HTTP消息中的SOAPAction中对应的值 ?????? 5.3 soapbind:body元素
<
operation?
name
="getBookPrice"
>
< soapbind:operation? style ="rpc" /> < 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? name ="submit" > ?? < soapbind:operation? style ="document" /> ?????? < input > ???????? < soapbind:body? use ="literal" ? /> ?????? </ input > ?????? < output > ???????? < soapbind:body? use ="literal" ? /> ?????? </ output > </ operation > soapbind:body元素有四个属性use、namespace、part和encodingStyle 对于WS-I?use的属性值必须是literal,意味这不是用编码的方式,所以永远不会用到encodingStyle属性 在RPC样式中,必须用一个有效的URI指定的namespace属性。此URI可以于WSDL文档的targetNampspce相同;而在document样式中不能使用namespace,XML文档样式的命名空间派生于它的XML文档 ??????????5.4 soapbind:fault元素
<
fault?
name
="InvalidArgumentFault"
>
????? < soapbind:fault? name ="InvalidArgumentFault" ?use ="literal" ? /> </ fault > < portType? name ="BookQuote" > ?? < operation? name ="getBookPrice" > ????? < input? name ="isbn" ?message ="mh:GetBookPriceRequest" /> ????? < output? name ="price" ?message ="mh:GetBookPriceResponse" /> ????? < fault? name ="InvalidArgumentFault" ?message ="mh:InvalidArgumentFault" /> ?? </ operation > </ portType > soapbind:fault元素和fault元素包含一个强制性的name属性,表示要引用声明于对应portType中的专有错误消息 ????????? 5.5 soapbind:header元素
<
types
>
< xsd:schema? targetNamespace ="http://www.Monson-Haefel.com/jwsbook/BookQuote" ?????xmlns ="http://www.w3.org/2001/XMLSchema" > ???????? < xsd:element? name ="message-id" ?type ="string" ? /> ???? </ xsd:schema > </ types > ? <!-- ?message?elements?describe?the?input?and?output?parameters? --> ?? < message? name ="Headers" > ???? < part? name ="message-id" ?element ="mh:message-id" ? /> ?? </ message > ? < operation? name ="getBookPrice" > ?? < input > ????? < soapbind:header? message ="mh:Headers" ?part ="message-id" ?use ="literal" ? /> ????? < soapbind:body? use ="literal" ???????????namespace ="http://www.Monson-Haefel.com/jwsbook/BookQuote" ? /> ???????? </ input > WSDL在绑定的input元素、output元素中利用soapbind:header元素显式指定了一个SOAP头文件 ??????? 5.6 soapbind:headerfault元素??
<!--
?message?elements?describe?the?input?and?output?parameters?
-->
?? < message? name ="HeaderFault" > ???? < part? name ="faultDetail" ?element ="mh:detailMessage" ? /> ?? </ message > ? < input > ?????? < soapbind:header? message ="mh:Header" ?use ="literal" > ????????? < soapbind:headerfault? message ="mh:Headers" ?use ="literal" ? /> ?????? </ soapbind:header > ?????? < soapbind:body? use ="literal" ???????????namespace ="http://www.Monson-Haefel.com/jwsbook/BookQuote" ? /> ??? </ input > soapbind:headerfault元素表述了Header专用的错误消息,如果有一个响应消息,必须在消息的Header元素中返回各种header的专用错误。 SOAP没有就如何提供Header错误方面给出详细说明,只是要求必须在Header元素中包含detail元素。有些SOAP工具箱将SOAP的fault放在header元素中。 六、WSDL实现:Service和Port元素
<
service?
name
="BookPriceService"
>
?? < port? name ="BookPrice_Port" ?binding ="mh:BookPrice_Binding" > ???? < soapbind:address? location = ?????"http://www.Monson-Haefel.com/jwsbook/BookQuote" ? /> ?? </ port > ?? < port? name ="BookPrice_Failover_Port" ?binding ="mh:BookPrice_Binding" > ???? < soapbind:address? location = ?????"http://www.monson-haefel.org/jwsbook/BookPrice" ? /> ?? </ port > ?? < port? name ="SubmitPurchaSEOrder_Port" ???binding ="mh:SubmitPurchaSEOrder_Binding" > ???? < soapbind:address? location = ?????"https://www.monson-haefel.org/jwsbook/po" ? /> ?? </ port > </ service > Service元素包含一个或者多个Port元素 每一个Port元素对应一个不同的Web服务,port将一个URL赋予一个特定的binding,通过location实现 可以使两个或者多个port元素将不同的URL赋给相同的binding,例如负载平衡和容错的时候,使用这种方法。 soapbind:address:将Internet地址通过location属性赋予一个SOAP绑定。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |