独立元素

  在SOAP中,
一个独立元素表示至少被一个多引用存取元素引用的类型的实例。所有的独立元素用soap:id属性作标记,而且这个属性的值在整个SOAP
envelope中必须是唯一的。独立的元素被编码就好象是它们被一个存取元素打包,这个存取元素的标记名是实例的名域限制的类型名。在上面的例子中,实
例的名域限制的类型名是t:adjustment。

  SOAP限制独立元素能被编码的场所。SOAP定义了一个能适用于任何元素的属
性:(soap:Package)。这个属性被用于控制独立元素能在哪里被解码。SOAP序列化规则指出独立元素必须编码为soap:Header元素或
soap:Body元素的直接子元素,或者是任何其它标记为soap:Package=‘true’的元素。通过把一个元素注释为包,你能保证编码那个实
例的XML元素是完全自包含的,并且在这个包以外没有任何引用到这个元素的多引用存取元素。

 
 假设transfer
类对应于一个方法请求。如果transfer类型不是一个包,被to和from存取元素引用的独立元素将作为soap:Body元素的直接子元素出现,如
图10所示。如果transfer类型是一个合法的SOAP包类型,编码可能象图11所示。注意,因为transfer元素是一个包,所有多引用存取器元
素都引用被包含的元素。这使得把transfer元素看成一个能从它的父辈元素中分离出的独立的XML代码段变得更为容易。

  多引用存取元素总是引用独立元素的模型是有一个例外的。SOAP允许包含字符串和二进值数据的存取元素是多引用存取元素的目标。这意味着下面的代码是合法的:

<t:mytype>
<field1 soap:href="#id1" />
<field2 soap:id="id1">Hello, SOAP</field2>
</t:mytype>

  尽管事实是存取元素2有一个soap:id属性,它实际上是一个存取元素而不是独立元素。

  SOAP数组

  数组被编码为组合类型的一个特殊的例子。在SOAP中,一个数组必须有一个秩(维数)和一个容量。一个数组被编码为一个组合类型,其中每一个数组元素被编码为一个子元素,这个子元素的名字是元素的名域限制的类型名。

  假设有下面的COM IDL类型定义:

struct POINTLIST {
long cElems;
[size_is(cElems)] POINT points[];
};
 
  这个类型的实例将被序列化为:

<t:POINTLIST xmlns:t=‘uri for POINTLIST‘>
<cElems>3</cElems>
<points xsd:type=‘t:POINT[3]‘ >
<POINT>lt;x>3</x>lt;y>4</y>lt;/POINT>
<POINT>lt;x>7</x>lt;y>5</y>lt;/POINT>
<POINT>lt;x>1</x>lt;y>9</y>lt;/POINT>
</points>
<t:POINTLIST>

  如果points域被标记为[ptr]属性,这个编码将用一个多引用存取元素,如下所示:
 
<t:POINTLIST xmlns:t=‘uri for POINTLIST‘>
<cElems>3</cElems>
<points soap:href="#x9" />
</t:POINTLIST>
<t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t:POINT[3]‘>
<POINT>lt;x>3</x>lt;y>4</y>lt;/POINT>
<POINT>lt;x>7</x>lt;y>5</y>lt;/POINT>
<POINT>lt;x>1</x>lt;y>9</y>lt;/POINT>
</t:ArrayOfPOINT>

  当把一个数组编码为一个独立元素时,标记名是带前缀ArrayOf的类型名。

  象NDR和CDR一样,SOAP支持部分转换的数组。如果子元素的数量少于所声明的容量,这些元素被假设正从数组的末尾丢失。这能够通过在正包含的数组元素上使用soap:offset属性来被忽略。

<t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t:POINT[5]‘
soap:offset=‘[1]‘>
<POINT>lt;x>1</x>lt;y>9</y>lt;/POINT>
</t:ArrayOfPOINT>

  soap:offset属性表示出现在数组中的第一个元素的索引。在上面的例子中,元素0,2到4都是不被转换的。SOAP也支持稀疏数组,这是通过使用soap:position属性来把每个元素用它的绝对索引来注释而实现的:

<t:ArrayOfPOINT soap:id=‘x9‘ xsd:type=‘t:POINT[9]‘>
<POINT soap:position=‘[3]‘>lt;x>3</x>lt;y>4</y>lt;/POINT>
<POINT soap:position=‘[7]‘>lt;x>4</x>lt;y>5</y>lt;/POINT>
</t:ArrayOfPOINT>

  在这个例子中,元素0到2,4到6,以及8到9都不是被转换的。

  请注意,在SOAP中数组的精确语法在这篇文章写作时还在被重新审查以调整到即将推出的W3C XML Schema规范中。要不断了解SOAP规范的最新版本来获得更多的细节。
 
错误处理

  一个服务器有时将不能正确地为一个方法请求提供服务。这可能是由于一般的HTTP错误造成的(如请求-URI不能被映射到本地的资源或一个HTTP级的安全违反)。也可能是在SOAP翻译软件中的问题,如马歇尔打包错误或一个必须的头不能被认出。 其它可能的原因包括一个请求不能正确地被服务,或者应用/对象代码决定要返回一个应用级的错误给调用者。这些情况在SOAP规范中都被清楚地加以处理。

  如果在分发对任何SOAP代码的调用之前一个错误发生在HTTP层,一个纯HTTP响应必须被返回。标准的HTTP状态代码编号将被采用,400级的代码表示一个客户引发的错误,500级的代码表示服务器引发的错误。这通常在代码执行前由Web服务器软件自动处理。

 
 假设在HTTP层一切正常,错误发生的下一个地方是在那些翻译和分发对应用代码(如COM对象和CORBA伺服对象)的SOAP调用。如果错误发生在这
一层,服务器必须返回一个错误消息来代替一个标准的响应消息。一个错误消息是下列被编码为soap:Body的根元素的类型的实例。

<schema
targetNamespace=‘urn:schemas-xmlsoap-org:soap.v1‘

<element name=‘Fault‘>
<type>
<element name=‘faultcode‘ type=‘string‘ />
<element name=‘faultstring‘ type=‘string‘ />
<element name=‘runcode‘ type=‘string‘ />
<element name=‘detail‘ />
</type>
</element>
 
</schema>
 
 
 faultcode存取元素必须包含一个用已知的整数表示的SOAP错误代码或者一个专门应用的名域限制的值。当前的SOAP
错误代码如图12所示。Faultstring存取元素包含对发生的错误的可读性的描述。runcode 存取元素包含一个字符串,它的值必须是Yes,
No或 Maybe,表明被请求的操作实际上是否在错误产生之前被执行。Detail存取元素是可选的,用于包含一个专门应用的异常对象。

  下面是一个对应于一个包含无法识别的必须的头元素的请求的SOAP错误的例子:

<soap:Envelope
xmlns:soap=‘urn:schemas-xmlsoap-org:soap.v1‘

<soap:Body>
<soap:Fault> ;
<faultcode>200</faultcode>
<faultstring>
Unrecognized ‘causality‘ header
</faultstring>
<runcode>No</runcode>
</soap:Fault>
</soap:Body>
</soap:Envelope>

  假设具体应用的错误需要被返回,你可能看到如图13所示的代码。在应用定义的错误的情况下,考虑应用的异常/错误对象时detail存取元素起到了soap:Body 元素的作用。

  奥秘

 
 一个遗留的HTTP问题还需要进一步阐明。SOAP支持(但不需要)HTTP扩展框架约定来指定必须的HTTP头扩展。这些约定主要有两个目的。首先,
它们允许任意的URI被用于限定给定的HTTP头的范围(象XML名域一样)。第二,这些约定允许把必须的头与可选的头区分开来(象
soap:mustUnderstand)。下面是一个使用HTTP扩展框架来把SOAPMethodName头定义成为一个必须的头扩展:

M-POST /foobar HTTP/1.1
Host: 209.110.197.2
Man: "urn:schemas-xmlsoap-org:soap.v1; ns=42"
42-SOAPMethodName: urn:bobnsid:IFoo#DoIt

  Man头映射SOAP URI到前缀为42的头,并表示没有认出SOAP的服务器必须返回一个HTTP错误,状态代码为501 (没有被实现) 或 510 (没有被扩展)。HTTP方法必须是M-POST,表明目前是必须的头扩展。

  结论

  SOAP是一个被类型化的序列化格式,它恰巧用HTTP 作为请求/响应消息传输协议。SOAP被设计为与正将出现的XML Schema规范密切配合,并支持在Internet的任何地方运行的COM, CORBA, Perl, Tcl, 和 Java-language, C, Python, 或 PHP 等程序间的互操作性。

  希望本文给了你一个对这个协议具体细节的更清晰的理解。我鼓励你用SOAP进行实验,或者试着使用SOAP使能的系统之一(列在http://www.develop.com/soap/),或者自己做一些工作。我本人发现采用脚本语言(Jscript),使一个基本的SOAP客户与服务器建立并运行只花费了不到一个小时。针对你对HTTP和XML的熟悉程度,以及你的目标平台的成熟度,你所花费的时间会有所不同。

我来自:向东博客

SOAP协议初级指南 (三)的更多相关文章

  1. SOAP协议初级指南 (一)

    SOAP(Simple Object Access Protocal) 技术有助于实现大量异构程序和平台之间的互操作性,从而使存在的应用能够被广泛的用户所访问.SOAP是把成熟的基于HTTP的WEB技 ...

  2. SOAP协议初级指南 (二)

    XML 作为一个更好的网络数据表达方式(NDR) HTTP是一个相当有用的RPC协议,它提供了IIOP或DCOM在组帧.连接管理以及序列化对象应用等方面大部分功能的支持.( 而且URLs与IORs和O ...

  3. 【JMeter4.0学习(三)】之SoapUI创建WebService接口模拟服务端以及JMeter对SOAP协议性能测试脚本开发

    目录: 创建WebService接口模拟服务端 下载SoapUI 新建MathUtil.wsdl文件 创建一个SOAP项目 接口模拟服务端配置以及启动 JMeter对SOAP协议性能测试脚本开发 [阐 ...

  4. 网络协议 20 - RPC 协议(上)- 基于XML的SOAP协议

    [前五篇]系列文章传送门: 网络协议 15 - P2P 协议:小种子大学问 网络协议 16 - DNS 协议:网络世界的地址簿 网络协议 17 - HTTPDNS:私人定制的 DNS 服务 网络协议 ...

  5. 使用CXF实现基于Soap协议的WebService

    本文介绍使用CXF实现基于Soap协议的WebService(CXF的版本是3.0.0) 一. 前言 Java有三种WebService规范:Jax-WS,Jax-RS,Jaxm 1. Jax-WS( ...

  6. Android与服务器端数据交互(基于SOAP协议整合android+webservice)

    http://www.cnblogs.com/zhangdongzi/archive/2011/04/19/2020688.html 上一节中我们通过http协议,采用HttpClient向服务器端a ...

  7. 【转载】SOAP协议介绍

    SOAP是用在分散或分布的环境中交换信息的简单的协议,它是一个基于XML的协议,包括三个部分:封装定义了一个描述消息中包含什么内容以及如何处理它们的框架,编码规则用于表示应用程序定义的数据类型的实例, ...

  8. http协议与soap协议之间的区别

    http是标准超文本传输协议.使用对参数进行编码并将参数作为键值对传递,还使用关联的请求语义.每个协议都包含一系列HTTP请求标头及其他一些信息,定义客户端向服务器请求哪些内容,服务器用一系列HTTP ...

  9. C#如何使用Soap协议调用WebService?

    WebService是什么?它的作用? WebService是一个平台独立.低耦合的.自包含的.基于可编程的可使用xml描述.调用的web应用程序,用于开发分布式的交互式的应用程序. Soap是什么? ...

随机推荐

  1. String s;和String s=null;和String s="a";有什么区别?

    String s;和String s=null;和String s="a";有什么区别?   针对这三种情况,使用out.println(s);的时候,第一个会出现异常,第二个会输 ...

  2. 关于调整TimePicker, DatePicker的大小,样式

    最近在做一个时间选择器,想把要DatePicker和TimePicker放在一起使用,无赖他们的大小样式是被Google写死了,找不到相应的属性来设置,自己花了点时间写了一个使用的Demo,运行的效果 ...

  3. python 之 Collections模块

    官方文档:https://yiyibooks.cn/xx/python_352/library/collections.html 参考: https://blog.csdn.net/songfreem ...

  4. IOZONE测试工具使用方法(转载)

    IOZONE主要用来测试操作系统文件系统性能的测试工具,该工具所测试的范围主要有,write , Re-write, Read, Re-Read, Random Read, Random Write, ...

  5. question?

  6. ORA-00600: 内部错误代码, 参数: [qctcte1]

    [情景再现] 生产环境,JAVA程序某功能报错: ORA-00600: 内部错误代码, 参数: [qctcte1], [0], [], [], [], [], [], [] [问题排查] 1.检查Or ...

  7. aop中通知详情

  8. Unity iOS 项目的一种性能评测方法

    [Unity iOS 项目的一种性能评测方法]

  9. Kafka总结的一张图

  10. Android开发实战之ViewPager的轮播

    在安卓开发的许多控件中,如果你没有使用过ViewPager,就不能算是一个安卓开发工程师,在本篇博文中,我会总结ViewPager的使用方法, 以及一些开发中的拓展.希望本篇博文对你的学习和工作有所帮 ...