WSDL 样式选择

WSDL 绑定样式可以是 RPC
样式或文档样式。用法可以是编码的,也可以是文字的。您如何决定使用哪一种样式/用法的组合呢?本文将帮助您解决这个问题。

Web 服务是通过 WSDL 文档来描述的。WSDL 绑定描述了如何把服务绑定到消息传递协议(特别是 SOAP
消息传递协议)。WSDL SOAP 绑定可以是 RPC 样式的绑定,也可以是文档样式的绑定。同样,SOAP
绑定可以有编码的用法,也可以有文字的用法。这给我们提供了四种样式/用法模型:

1.       
RPC/编码

2.       
RPC/文字

3.       
文档/编码

4.       
文档/文字

除了这些样式之外,还有一种样式也很常见,它称为文档/文字包装的样式,算上这一种,在创建 WSDL
文件时您就有了五种绑定样式可以从中选择。您应该选择哪一种呢?

对于本文的讨论,让我们从 清单1中的 Java 方法开始,并且对其应用
JAX-RPC Java-to-WSDL 规则。




public void myMethod(int
x);

采用 清单1中的方法并且使用您喜欢的 Java-to-WSDL
工具来运行它,指定您想让它生成 RPC/编码的 WSDL。您最后应该得到如 清单2所示的 WSDL 片断。





<message
name="myMethodRequest">

<part
name="x" type="xsd:int"/>

</message>

<message
name="empty"/>

<portType
name="PT">

<operation name="myMethod">

<input
message="myMethodRequest"/>

<output
message="empty"/>

</operation>

</portType>

<binding
.../>

<!-- I won‘t bother with
the details, just assume it‘s RPC/encoded. -->

现在用“5”作为参数x 的值来调用此方法。我们将发送一个与 清单3类似的 SOAP 消息。




<soap:envelope>

<soap:body>

<myMethod>

<x xsi:type="xsd:int">5</x>

</myMethod>

</soap:body>

</soap:envelope>









为了简单起见,在本文的大部分 XML
示例中,我省略了名称空间和前缀。不过,我还是使用了少数前缀,您可以假定它们是用下列名称空间进行定义的。

  • xmlns:xsd="http://www.w3.org/2001/XMLSchema"

  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  • xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

对于这个 RPC/编码的示例中的 WSDL 和 SOAP 消息,有许多需要注意的事项:

  • WSDL 基本达到了尽可能地简单易懂的要求。

  • 操作名出现在消息中,这样接收者就可以很轻松地把消息发送到方法的实现。

  • 类型编码信息(比如xsi:type="xsd:int")通常就是降低吞吐量性能的开销。

  • 您不能简单地检验此消息的有效性,因为只有<x
    xsi:type="xsd:int">5</x>行包含在 Schema 中定义的内容;其余的soap:body内容都来自 WSDL
    定义。

有没有一种方法能够保留这些优点而消除其中的缺点呢?或许有。让我们来看一看 RPC/文字的样式。

用于我们的方法的 RPC/文字的 WSDL 看起来与 RPC/编码的 WSDL 几乎一样(请参见 清单4)。只是绑定的用法由编码改为文字。仅此而已。




<message
name="myMethodRequest">

<part
name="x" type="xsd:int"/>

</message>

<message
name="empty"/>

<portType
name="PT">

<operation name="myMethod">

<input
message="myMethodRequest"/>

<output
message="empty"/>

</operation>

</portType>

<binding
.../>

<!-- I won‘t bother with
the details, just assume it‘s RPC/

literal. -->

RPC/文字的 SOAP 消息又是怎样的呢(请参见 清单 5)?这里的更改要多一点。去掉了类型编码。




<soap:envelope>

<soap:body>

<myMethod>

<x>5</x>

</myMethod>

</soap:body>

</soap:envelope>

下面是这种方法的优点和缺点:

  • WSDL 还是基本达到了尽可能地简单易懂的要求。

  • 操作名仍然出现在消息中。

  • 去掉了类型编码。

  • 您仍然不能简单地检验此消息的有效性,因为只有<x
    xsi:type="xsd:int">5</x>行包含在 Schema 中定义的内容;其余的soap:body内容都来自 WSDL
    定义。

文档样式如何呢?它们能够帮助克服这些困难吗?

我不知道有谁懂得这种方法的真正含义。我也不知道这种方法的任何实现。它将可能从 WSDL
的后续版本中消失。所以我们还是讨论别的吧。

文档/文字的 WSDL 对 RPC/文字的 WSDL 作了一些更改。它们之间的不同之处显示在 清单6中。




<types>

   
<schema>

       
<element name="xElement" type="xsd:int"/>

   
</schema>

</types>

<message
name="myMethodRequest">

<part
name="x"

element="xElement"/>

</message>

<message
name="empty"/>

<portType
name="PT">

<operation name="myMethod">

<input
message="myMethodRequest"/>

<output
message="empty"/>

</operation>

</portType>

<binding
.../>

<!-- I won‘t bother with
the details, just assume it‘s

document/literal. -->

而现在的 SOAP 应该如 清单 7所示:




<soap:envelope>

<soap:body>

<xElement>5</xElement>

</soap:body>

</soap:envelope>








我本来可以只更改绑定,就像我从 RPC/编码转到 RPC/所做的那样。它将是合法的
WSDL。然而,WS-I 基本概要(WS-I Basic Profile)(请参见 参考资料)规定文档/文字的消息的组成部分引用元素而不是类型,所以我遵循了
WS-I(并且此处使用元素部分可以很好地把我们带到关于文档/文字包装的样式的讨论)。


下面是这种方法的优点和缺点:

  • 没有编码信息

  • 您可以在最后用任何 XML
    检验器检验此消息的有效性。soap:body(<xElement>5</xElement>)中每项内容都定义在 Schema 中。

  • WSDL 变得有些复杂。不过,这是一个非常小的缺点,因为 WSDL
    并没有打算由人来读取。

  • SOAP 消息中缺少操作名。而如果没有操作名,发送就可能比较困难,并且有时变得不可能。

文档/文字的样式看起来似乎只是重新安排了
RPC/文字的模型的优点和缺点。您可以检验消息的有效性,但是您失去了操作名。有没有一种方法可以改进这一点呢?有的。它就是文档/文字包装的样式。

在我说明文档/文字包装的样式的含义之前,让我给您展示 清单 8清单9中的 WSDL 和 SOAP 消息。




<types>

<schema>

<element name="myMethod"/>

           <complexType>

               
<sequence>

                   
<element name="x" type="xsd:int"/>

               
</sequence>

           
</complexType>

       
</element>

</schema>

</types>

<message
name="myMethodRequest">

<part
name="

parameters" element="

myMethod"/>

</message>

<message
name="empty"/>

<portType
name="PT">

<operation name="myMethod">

<input
message="myMethodRequest"/>

<output
message="empty"/>

</operation>

</portType>

<binding .../>

<!-- I won‘t bother with
the details, just assume it‘s document/literal. -->

WSDL Schema 现在把参数放在包装中(请参见 清单9)。




<soap:envelope>

<soap:body>

<myMethod>

<x>5</x>

</myMethod>

</soap:body>

</soap:envelope>

注意到此 SOAP 消息看起来非常类似于 RPC/文字的 SOAP 消息。您可能会说,它看起来与 RPC/文字的 SOAP
消息是完全一样的,不过,这两种消息之间存在着微妙的区别。在 RPC/文字的 SOAP
消息中,<soap:body>的<myMethod>子句是操作的名称。在文档/文字包装的 SOAP
消息中,<myMethod>子句是单个输入消息的组成部分引用的元素的名称。因此,包装的样式具有这样的一个特征,输入元素的名称与操作的名称是相同的。此样式是把操作名放入
SOAP 消息的一种巧妙方式。

文档/文字包装的样式的特征有:

  • 输入消息只有一个组成部分。

  • 该部分就是一个元素。

  • 该元素有与操作相同的名称。

  • 该元素的复杂类型没有属性。

下面是这种方法的优点和缺点:

  • 没有编码信息。

  • 出现在 soap:body 中的每项内容都是由 Schema
    定义的,所以您现在可以很容易地检验此消息的有效性。

  • 方法名又出现在 SOAP 消息中。

  • WSDL 甚至更复杂,但是这仍然是一个非常小的缺点。

如您所见,文档/文字包装的样式还是有一些缺点,不过与优点比起来,它们都显得无足轻重。








从 WSDL 的角度来看,没有理由只是把把包装的样式和文档/文字绑定联系在一起。它可以很容易地应用于
RPC/文字绑定。但是这样做是相当不明智的。SOAP
将包含操作的一个myMethod元素和元素名称的子myMethod元素。另外,即使它是一个合法的 WSDL,RPC/文字元素部分也不遵循
WS-I。

这种包装的样式来源于
Microsoft。没有定义这种样式的规范;所以虽然这种样式是一个好的东西,但不幸的是,为了与 Microsoft
和其他公司的实现进行互操作,现在惟一的选择就是根据 Microsoft WSDL 的输出来猜测它是如何工作的。文档/文字包装的样式也实现在 IBM
WebSphere SDK for Web Services 中(请参见 参考资料)。在这个示例中,样式是相当明显的;但是也存在个别情况,在这些情况中,由于缺少定义而导致需要操作的适当事项不够特别清晰。我们希望看到的最理想的情况就是将来能有像
Web 服务互操作组织(Web Services Interoperability
Organization)这样的独立团体来帮助对此进行稳定化和标准化。

至此,本文已经给了您这样的一个印象,文档/文字包装的样式是最好的方法。而实际的情况往往确实如此。不过,仍然存在着一些情况,在这些情况下,您最好是换一种别的样式。

如果您已经重载了操作,就不能采用文档/文字包装的样式。

想象一下,除了我们一直在使用的方法之外,还有另一种方法,请参见 清单10




public void myMethod(int
x);

public
void myMethod(int x, String y);








WSDL 的下一个版本可能将不允许重载的操作。


WSDL 允许重载的操作。但是当您添加包装的样式到 WSDL 时,需要元素有与操作相同的名称,并且在 XML
中不能有两个名称相同的元素。所以您必须采用文档/文字非包装的样式或某种 RPC 样式。

由于文档/文字非包装的样式没有提供操作名,所以在有些情况下,您将需要采用某种 RPC 样式。比如说 清单11中的一组方法。




public void myMethod(int
x);

public void myMethod(int x,
String y);

public
void someOtherMethod(int x);

现在假定您的服务器接收到文档/文字的 SOAP 消息(您可以回过头在 清单 7中看一看它)。服务器应该发送哪一种方法呢?所有您能确切知道的就是,它一定不是myMethod(int
x, String
x),因为消息只有一个参数,而这种方法需要两个参数。它可能是其他两种方法中的一种。采用文档/文字的样式,您没有办法知道是哪一种方法。

假定服务器接收到一个 RPC/文字的消息(比如 清单5中的),而不是文档/文字的消息。对于这种消息,服务器很容易决定把它发送到哪一种方法。您知道操作名是myMethod,并且也知道只有一个参数,所以它必定是myMethod(int
x)。

采用 RPC/编码的理由有很多。其中两个主要的原因是:

  • 数据图形

  • 多态性

数据图形

设想您有一个二进制树,其中的节点定义在 清单12中。





<complexType
name="Node">

<sequence>

<element
name="name" type="xsd:string"/>

<element
name="left" type="Node" xsd:nillable="true"/>

<element
name="right" type="Node" xsd:nillable="true"/>

</sequence>

</complexType>

根据这种节点定义,我们可以构造一个树形结构,它的根节点 A 通过它左边和右边的的链接可以指向节点 B(请参见 图1)。

发送数据图形的标准方式是使用 href 标记,它是 RPC/编码的样式( 清单13)的一部分。





<A>

<name>A</name>

<left
href="12345"/>

<right
href="12345"/>

</A>

<B id="12345">

<name>B</name>

<left
xsi:nil="true"/>

<right
xsi:nil="true"/>

</B>

在任何文字的样式中,href 属性都是不可用的,这样图形链接就不再起作用了( 清单14图2)。您仍然有一个根节点 A,它从左边指向一个节点
B,从右边指向另一个节点 B。这两个 B 节点是等同的,但它们不是相同的节点。是复制了数据而不是引用了两次数据。





<A>

<name>A</name>

<left>

<name>B</name>

<left
xsi:nil="true"/>

<right
xsi:nil="true"/>

</left>

<right>

<name>B</name>

<left
xsi:nil="true"/>

<right
xsi:nil="true"/>

</right>

</A>

在文字样式中,您可以通过各种方法构造图形,但是却没有标准的方法;所以您做的任何事情很可能不能与网络中其他端点上的服务进行互操作。

多态性

看一看 清单15中使用多态性 Schema 的
WSDL。





<types>

<schema>

<complexType name="animal">

<sequence>

<element
name="name" type="xsd:string"/>

</sequence>

</complexType>

<complexType name="dog">

<complexContent mixed="false">

<extension
base="animal">

<sequence>

<element name="breed" type="xsd:string"/>

</sequence>

</extension>

</complexContent>

</complexType>

</schema>

</types>

<message
name="in">

<part name="trainee"
type="animal"/>

</message>

<message
name="empty"/>

<portType
name="AnimalTrainer">

<operation
name="train">

<input
message="in"/>

<output
message="empty"/>

</operation>

</portType>

当您把一个 dog 的实例传送给train操作时,所生成的 SOAP
消息必须包含类型编码信息,这样接收终端才能知道它所接收的是 animal 的哪一个扩展(请参见 清单16)。这种类型编码信息可用在
RPC/编码的样式中。




<soap:envelope>

<soap:body>

<train>

<trainee xsi:type="Dog">

<name>Bob</name>

<breed>Bloodhound</breed>

</trainee>

</train>

</soap:body>

</soap:envelope>

有四种绑定样式(其实真正有五种,不过文档/编码的样式没有什么意义)。虽然每种样式都有自己的用武之地,但是在大多数情况下,最好的样式是文档/文字包装的样式。

时间: 2024-10-21 03:38:43

WSDL 样式选择的相关文章

canvas线性变换、颜色和样式选择

1.应用不同的线型 ctx.lineWidth = value; 线条的宽度,默认为1 ctx.lineCap = type; 设置端点样式, type默认为butt,可选值round,square,butt ctx.lineJoin = type; 设置连接处样式,type默认为miter,可选值round,bevel,miter ctx.miterLimit = value; 设置绘制交点的方式,miterLimit属性的作用是斜面的长度设置一个上线,默认为10,当斜面的长度达到线条宽度的1

3.6html学习笔记之样式选择

1.元素选择器 *{padding:0;margin:0;} p,span{} 2.类选择器 *.class{} p.class{} <p class="important class1"> 3.id选择器 #id为x的元素 4.属性选择器 *[title]{color:red}有这个属性的 5.后代选择器: 空格(后代).>(子代).+(紧邻) 子元素 6.伪类选择器: 自身元素 a:visited{} a:link{} a:hover{} a:active{}

城市样式选择,类宝岛眼镜城市选择

help.js: (function (document) {    window.HELP = window.HELP || {};    HELP.redrawSelect = function () {        $("select").each(function () {            HELP.redrawSelectByObj($(this));        });    } HELP.redrawSelectByObj = function (obj) { 

HTML/CSS 选择符优先级

CSS的选择符优先级 1.同级样式默认后者覆盖前者 2.样式优先级 类型(1) < class[type](10)=伪类(10) < id(100) < style行间样式(1000) < style内部样式 < link外部引入样式 选择符的相应值综合相加起来大的优先级高 注 : 相应值仅仅是代表他们的等级, 11个类型选择符的优先级仍然小于1个类选择符,以此类推 3.important(IE7及以上) 加了important的样式属性优先级最高. 例 .box{backg

HTML文档中应用css样式的方法总结

在HTML文档中应用css样式大致有三种方法:1.link标签链接外部样式表:2.使用style元素包含样式表:3.使用style属性,即内联样式 一.link标签链接外部样式表 先看一条较为标准的link标记语句: <link rel="stylesheet" type="text/css" href="main.css" media="all" /> link标记必须放在head元素中,且不能放在其他元素(如t

HTML标签、选择符、超链接以及SEO

常见标签: <div>块</div> img标签是个单标签 alt作用 图片加载失败 显示alt中内容 <img src="图片名字" alt="图片的名字"/> a标签详细介绍: a标签的链接实现: <a href = "链接" target="_blank">a标签 </a> 点击a标签 会转到相应链接下控制链接新打开一个页面用或者其他用target,还有self

WSDL

WSDL文件是测试基于soap的服务,他们定义实际暴露服务和要求SoapUI生成测试,要求信息,验证和MockServices. SoapUI支持最广泛使用的1.1版本的WSDL和SOAP 1.1和1.2对应绑定. 让我们挖到WSDL相关功能SoapUI通过创建一个新项目并导入一个简单的公开可用的WSDL(http://www.webservicex.com/CurrencyConvertor.asmx?wsdl),在SoapUI工作区中创建一个新项目如下: 按下OK后,SoapUI将指定的WS

css 样式引入的方法 link 与import的区别

<link> 元素所参考的样式用户可以自由的选择加以改变,而导入的样式表单就自动的与剩下的样式表融合在一起了 CSS与HTML文档结合的4中方法:1 使用<link>元素链接到外部的样式文件2 在<head>元素中使用"style"元素来指定3 使用CSS "@import"标记来导入样式表单4 在<body>内部的元素中使用"style"属性来定义样式 1 用link进行引用 <link r

高级选项更改MathType数学公式样式

MathType中系统的样式有很多种,我们将通过示例来演示如何更改样式定义达到修改等式的目的.使用样式将允许你迅速且方便的获得一种格式,这种格式将使你创建的等式具有统一的风格. 以下步骤中,我们将创建这样一个等式: 点击“高级”选项,里面有大量的设置选项的样式定义,如下图所示: MathType定义样式之“高级”按钮 对函数样式选择一种新的字体.样式默认为Times New Roman,在函数项目栏字体右侧点击向下箭头打开字体下拉菜单并选择一种不同的字体.选择一种看起来和Times New Ro