一、SOAP协议概述
soap简单对象访问协议,是一个用来在分散/分布式的环境中交换信息的简单协议,
是一个基于xml的协议。
soap本身是一个无状态的、单向的消息交换机制。
soap中没有包含应用于soap消息路由、可靠数据传输和穿越防火墙等方面的应用
程序数据传送语义,但是它提供了一个机制,通过这个机制,特定于应用程序的信息
能够以一种可靠的方式传送。
soap协议包含4个部分:
1、soap封装:封装定义了一个描述消息中的内容是很么、似乎谁发送的、谁应当接受
并处理它以及如何处理它们的框架。
2、soap编码规则:用于表示应用程序需要使用的数据类型的实例,即如何把语言类型
映射到soap消息中的xml上。
3、soap RPC表示:描述如何使用soap进行远程过程调用和响应。
4、soap绑定:描述如何使用底层协议交换信息。soap规范中包含一个默认的http绑定,
它定义了如何通过http交换soap消息。
术语:
1、soap节点:soap节点按照soap定义的约定处理soap消息,它有责任实施控制soap
消息交换和通过soap绑定访问底层协议的规则。如果发现与soap约定不兼容的情况,
则soap节点将产生一个soap错误。
2、soap发送者:指发送soap消息的soap节点。
3、soap接收者:指接收soap消息的节点。
4、soap消息路径:一个soap消息在传输中要通过一系列的发送者和接收者节点,
包括初始的soap发送者、0个或多个中间节点以及最终的soap接收者,
这些节点就构成了soap消息路径。
所有的soap消息都是用xml进行编码。一个soap节点必须保证它所产生的消息中的
所有元素和属性都必须使用命名空间进行正确地限定。soap节点必须能够处理它所
接受的消息中的soap命名空间信息,也必须忽略包含不正确命名信息的消息。
soap定义了以下常用的命名空间:
1:soap封装对应的命名空间是”http://schemas.xmlsoap.org/2001/12/soap-enve
lope/”,通常使用env前缀表示。
2:soap序列化对应的命名空间为”http://www.w3.org/2001/12/soap-encoding”,
通常使用enc前缀表示。
3:RPC对应的命名空间为”http://www.w3.org/2001/12/soap-rpc”。
4:soap错误的命名空间是”http://www.w3.org/2001/12/soap-faults”.
soap消息中一定不能包含DTD。当soap接收者收到一条包含dtd的soap消息时,
必须要产生一个DTDNotSupported错误。soap消息中也不应包括处理指令,
soap接收者将忽略soap消息中的处理指令。
soap消息不能要求任何接受节点执行xml架构验证,因此,soap要求所有的属性
都包含在序列化或的soap封装中。
二、SOAP消息
一、soap消息完全基于xml,它包含以下部分:
1、封装(Envelope):是表示soap消息的顶级元素,是必需的。Envelope元素包含两个子元素Header和Body元素,这两个元素中的内容是由应用程序定义的并且不属于soap规范。
2、 报头(Header):是可选的,是一种用来以分散方式向soap消息上添加额外特性的通用机制。通过这种机制添加额外特性时不需要得到通信双方的实现同 意。正是通过这种机制,应用程序才能以特定的方式对soap消息进行扩充。报头的直接子元素成为报头条目,它表示一些逻辑数据分组,可被传输路径中的 soap节点进行处理。把那些数据放到报头条目中是在设计应用程序时确定的。
3、报体(Body):是一个包含发送给最终目标节点的必需信息的容器,是必需的。
soap消息可以被不同的底层协议传输。例如,在web环境中,它可以放在http post请求的消息主体中进行传输,或者也可以使用电子邮件进行发送。
二、
SOAP消息
1、Envelope元素
soap封装对应的元素是Envelope,它是soap消息的顶级元素,必须要出现在soap消息中,并且,报头和报体都是必须位于Envelope元素中。
在Envelope中可以包含命名空间声明和其他一些属性,并且这些属性必须要使用命名空间进行限定。
例如,在下面的Envelope元素的声明中就包含了一个命名空间声明SOAP-ENV和一个属性encodingStyle:
<ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope”
ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/endoding/”>
</ENV:Envelope>
(1)encodingStyle属性
encodingStyle 全局属性用来指定soap消息的序列化规则,它所属的命名空间为”http://www.w3.org/2001/12/soap-envelope”。 这个属性可以在任何元素中出现,它的作用范围为包含它的元素,包含该元素的所有子元素(除非子元素包含自己的encodingStyle属性),这与 xml命名空间声明的作用范围类似。另外,soap消息没有默认的编码规则。
encodingStyle属性值的类型是anyURI,它的值指定了一组用来反序列化soap消息的序列化规则,例如:
encodingStyle=”http://www.w3.org/2001/12/soap-encoding”
encodingStyle=”http://example.org/encoding”
encodingStyle=””
soap 定义的序列化规则通过”http://www.w3.org/2001/12/soap-encoding”来标识。使用这个特定序列化规则的soap消 息应该使用encodingStyle属性明确指出。另外,所有以”http://www.w3.org/2001/12/soap-encoding” 开头的URI表示与soap编码规则一致,但是可以添加更严格的规则。
零长度的URI(“”)明确指出所含元素没有任何编码形式。这可以用来取消上一级元素的所有编码声明。
(2)Envelope的版本模型
soap 没有定义传统的基本于主版本号与次版本号的版本模型。如果soap节点所收到的soap消息的Envelope元素的命名空间不 是”http://www.w3.org/2001/12/soap-envelope”,则这个soap节点将认为这是一个版本错误并产生一条 VersionMismatch错误。任何其他的消息结构差异都被看作是Sender错误。
2、Header元素
这个元素是可选的,如果出现,则必须是Envelope元素的第一个子元素,并使用命名空间进行完全限定。Header元素中可以包含一些属性和报头条目,每一个条目都是Header的直接子元素,并且必须要使用命名空间进行限定。
在 Header元素中可以使用encodingStyle属性指出报头条目使用的编码方式,另外,还可以使用mustUnderstand和actor属性 来指出如何处理该条目以及由谁处理。这些属性只能在Header元素的直接子元素中使用,soap消息接收者必须忽略那些没有应用到直接子元素上的属性。
(1)actor属性
soap 消息在发往最终目标的途中可能会经过许多中间节点,这些中间节点既能接收又能转发soap消息。并不是soap消息的所有部分都发给最终目标节点,其中一 部分可能由消息路径中的中间节点进行处理。actor属性就是用来指定soap报头条目所定向的节点。它所属的命名空间 为”http://www.w3.org/2001/12/soap-envelope”,在使用时必须使用命名空间对其进行限定。actor属性值的类 型为anyURI,它指定了一个soap节点所扮演的角色。省略actor属性的报头条目隐含地定向到最终soap接收者,属性值为空等效于完全省略该属 性。如果报头条目中的soap actor与某个soap节点的角色匹配(没有actor属性时,与最终接收者匹配),就认为这个报头条目定向到这个soap节点上。
在 soap消息处理过程中,soap节点起到一个或多个actor的作用,其中每一个都通过URI指出。每一个soap节点都必须完 成”http://www.w3.org/2001/12/soap-envelope/actor/next”所指定的actor的作用,并且可以完成 其他0个或多个actor的作用。
每一个接收到包含actor属性值为next的报头条目的消息的soap处理器都必须处理这个元素的内容,这也是每一个soap节点的标准角色。具有next属性的Header元素期望被消息路径中的下一个soap处理器所处理。
(2)mustUnderstand属性
用来指出报头条目对于目标soap节点来说是必须处理的还是可选的。mustUnderstand属性值是一个boolean值默认为false。
如果一个soap节点上的软件完全符合并实现了一个报头条目的最外层元素的局部名称和命名空间名词所表示的语义,责称这个soap节点理解这个报头条目。
当mustUnderstand属性值是true或1时,责称这个报头条目是强制的。对于每一个强制的soap报头条目,它所定向的节点必须根据该条目最外层元素的局部名称和命名空间名称所定义的语义进行处理,或者根本不处理并产生一条错误。
强制条目意味着必须以某种方式修改其他报头或报体元素的语义,所以标记为强制性的报头条目可以确保这个语义改变不会被无故忽略。
3、Body元素
它是Envelope元素的直接子元素并且必须出现在soap消息中,它通过完全限定名标识。
Body元素中可以包含一些条目,每一个条目都是它的直接子元素,并且必须使用命名空间进行限定。用户可以在Body元素中使用encodingStyle属性来指出这些条目所使用的编码方式。
Body元素的典型用法包括调度RPC调用和错误报告。soap定义了一个报体条目Fault,它用来报告错误。
如果报头条目的actor属性为默认值0,并且mustUnderstand属性值为1,则它们与报体条目在语义上是等效的,即都必须被最终目标节点所处理。
4、Fault元素
当在处理消息的过程中发生错误时,soap Fault元素用来在soap消息中携带错误和/或状态信息。如果消息中包含Fault元素,则它必须作为Body元素的直接子元素出现,并且最多只能出现一次。
Fault元素定义了以下4个子元素:
(1)faultcode:用来提供一个识别错误的算法机制。Fault元素必须包含该子元素,并且它的值必须是一个限定名。soap定义一些soap错误代码来描述基本的soap错误。(略)
(2)faultstring:用来提供一个肉眼可以读的错误解释,类似于http中定义的状态码简短描述,必须包含在Fault元素中,并且应该提供一些对错误性质的解释信息。
(3)faultactor:用来标识导致错误发生的soap节点,它的值是一个URI。类似于actor属性,只不过actor属性指定的是报头条目的目标节点,而该元素指定的则是错误的来源。如果不包含该元素,则表示错误的来源是最终接收者。
(4)detail:用来携带与Body元素相关的特定于应用程序的错误信息。如果Body元素的内容不能被成功的处理,则必须包含detail子元素。
detail元素的所有直接子元素称作细目,并且每个细目在detail元素中编码为独立的元素。细目的编目规则如下:一个细目由它的完全限定名(包括命名空间URI和局部名)确定,可以在细目元素中使用encodingStyle属性来指出细目的编码形式。