SOAP传输协议

2023-05-16

一.HTTP传输协议

超文本传输协议(HyperText Transfer Protocol,缩写:HTTP),它是基于请求-响应的模式协议,客户端发出请求,服务器端给出响应并返回请求内容。方法如下,HTTP传输协议常用的也就是GET和POST两种方法,下面的SOAP协议常使用到的也是GET和POST两种方式。

方法  含义
GET向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问
HEAD与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)
POST  向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有
PUT  向指定资源位置上传其最新内容
DELETE 请求服务器删除Request-URI所标识的资源
TRACE  回显服务器收到的请求,主要用于测试或诊断
OPTIONS  这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作
CONNECT  HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)

======================================================================

二.SOAP传输协议

SOAP(Simple Object Accrss Protocol,简单对象访问协议)是一种简单的基于XML的协议,SOAP是Web Service的通信协议,是基于XML语言和XSD标准,其定义了一套编码规则,编码规则定义如何将数据表示为消息,以及怎样通过HTTP协议来传输SOAP消息,由四部分组成:

(1) SOAP信封(Envelope):定义了一个框架,框架描述了消息中的内容是什么,包括消息的内容、发送者、接收者、处理者以及如何处理消息。

(2)SOAP编码规则:定义了一种系列化机制,用于交换应用程序所定义的数据类型的实例。(3) SOAP RPC表示:定义了用于表示远程过程调用和应答协定。

(4)SOAP绑定:定义了一种使用底层传输协议来完成在节点间交换SOAP信封的约定。

soap将信息进行XML的序列化后,再用http协议的方式再打包进行传送,传送的方式还是tcp或者udp。做个比喻就好理解了。tcp 和 udp 都是公路,暂且把tcp认为是一般公路,udp高速公路,soap和http就都是汽车,那么soap和http都可以在tcp和udp上跑。说soap可以通过http来传送,实际就是说soap是小轿车,http是装轿车的卡车,把soap的信息装到http里面,然后再运输,当然走的道路还是tcp或udp。说soap可以通过http协议来传输,这句话不太准确,比较准确第说法是:soap信息可以通过http协议包装后通过tcp或udp传输。

//SOPA协议的基本结构
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
<soap:Header>
  ...
  ...
</soap:Header>
 
<soap:Body>
  ...
  ...
  <soap:Fault>
    ...
    ...
  </soap:Fault>
</soap:Body>
 
</soap:Envelope>

========================================================================

三.SOAP传输协议
1.SOAP Envelope

SOAP Envelope是代表消息的XML文件的根元素。它为消息如何处理、由谁处理定义了框架。XML内容从SOAP Envelope开始。在SOAP中,使用XML命名空间将SOAP标示符与应用程序特定的标示符区分开,将SOAP消息的元素的作用域限制在一个特定的领域。如果使用了不同的命名空间,应用程序会发生错误,并抛弃此消息。SOAP消息中所有元素必须由第一个命名空间进行限定。

SOAP 1.1规范如下:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"

</soap-env:Envelope >

SOAP 1.2规范如下:

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"

</soap:Envelope>

2.encodingStyle属性

 SOAP的encodingStyle属性用于定义在文档中使用的数据类型,encodingStyle属性可出现在任何SOAP元素中,并会被应用到元素的内容及元素的所有子元素上。SOAP消息没有默认的编码方式。

3.SOAP Header元素

 SOAP Header元素应当作为SOAP Envelope的第一个直接子元素,必须使用有效的命名空间。Header还可以包含0个或多个可选的子元素,子元素称为Header项,所有的Header项都必须是完整修饰的,即必须由一个命名空间URI和局部名组成,不允许没有命名空间修饰的Header项存在。

Header元素用于与消息一起传输附加消息,如身份验证或事务信息。Header元素也可以包含某些属性。SOAP在默认的命名空间中定义了三个属性:actor,mustUnderstand以及encodingStyle。这些被定义在SOAP头部的属性可通知容器如何对SOAP消息进行处理。

<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap:mustUnderstand="1">234</m:Trans>
</soap:Header>
 
...
</soap:Envelope>

3.1actor属性

通过沿着消息路径经过不同的端点,SOAP消息可从某个发送者传播到某个接收者。并非SOAP消息的所有部分均打算传送到SOAP 消息的最终端点,也可以传输到某一个特定的端点上。SOAP的actor属性可被用于将Header元素寻址到一个特定的端点。

//语法规则:soap:actor="URI"
//下面代码中有一个"Trans"元素的头部,值是234,此元素的"mustUnderstand"属性的值是"1"。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap:actor="http://www.w3school.com.cn/appml/">
234
</m:Trans>
</soap:Header>
 
...
...
 
</soap:Envelope>

3.2mustUnderstand属性

SOAP的mustUnderstand属性可用于标识标题项对于要对其进行处理的接收者来说是强制的还是可选的。假如向Header元素的某个子元素添加了"mustUnderstand="1",则它可指示处理此头部的接收者必须认可此元素。假如此接收者无法认可此元素,则在处理此头部时必须失效。

//语法:soap:mustUnderstand="0|1"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
<soap:Header>
<m:Trans
xmlns:m="http://www.w3school.com.cn/transaction/"
soap:mustUnderstand="1">
234
</m:Trans>
</soap:Header>
 
...
...
 
</soap:Envelope>

3.3encodingStyle属性

SOAP的encodingStyle属性与Envelope元素中相同。

=========================================================================

4.SOAP Body元素

  SOAP消息的Body块可以包含以下任何元素:RPC方法及其参数;目标应用程序(消息接收者)专用数据;报告故障和状态消息的SOAP Fault。所有Body元素的直接子元素都称为Body项,Body项必须由命名空间修饰。必需的SOAP Body元素可包含打算传送到消息最终端点的实际 SOAP消息。

SOAP Body元素的直接子元素可以是合格的命名空间。SOAP在默认的命名空间中("http://www.w3.org/2001/12/soap-envelope")定义了Body元素内部的一个元素。即SOAP的Fault元素,用于指示错误消息。

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
 
<soap:Body>
   <m:GetPriceResponse xmlns:m="http://www.w3school.com.cn/prices">
      <m:Price>1.90</m:Price>
   </m:GetPriceResponse>
</soap:Body>
 
</soap:Envelope>

=========================================================================

5.SOAP Fault元素

SOAP Fault元素用于在SOAP消息中传输错误及状态信息。如果SOAP消息需要包括SOAP Fault元素,SOAP Fault元素必须作为一个Body项出现,而且至多出现一次。SOAP Fault包括以下子元素:faultcode、faultstring、faultactor、detail。

子元素

描述

<faultcode>

供识别故障的代码

<faultstring>

可供人阅读的有关故障的说明

<faultactor>

有关是谁引发故障的信息

<detail>

存留涉及 Body 元素的应用程序专用错误信息

SOAP的Fault元素拥有下列子元素, 在下面定义的 faultcode 值必须用于描述错误时的 faultcode 元素中:

VersionMismatch

SOAP Envelope 元素的无效命名空间被发现

MustUnderstand

Header 元素的一个直接子元素(带有设置为 "1" 的 mustUnderstand 属性)无法被理解。

Client

消息被不正确地构成,或包含了不正确的信息。

Server

服务器有问题,因此无法处理进行下去。

=========================================================================

6.SOAP附件

按照SOAP1.1规范的规定,SOAP消息可以包含XML格式的主SOAP信封,以及包含ASCII或二进制等任何数据格式的SOAP附件。如果SOAP消息包含附件,那么SOAP消息将是一个MIME编码的消息,包含SOAP内容和一个或多个其他类型的附件。因此SOAP消息实际上分为以下两种类型:

    A、仅包含XML内容的消息

    B、MIME编码的消息,包含初始的XML有效内容以及任何数量的附件。附件可以是任何其他类型的数据。

=========================================================================

7.SOAP消息绑定

Web服务的有效负载通常包装在SOAP消息中,而SOAP消息结构由WSDL文档中的SOAP绑定定义确定。不同的调用方式和编码方式通过组合可以产生多种绑定样式,而每种样式的应用场景和对应的SOAP消息结构并不相同。如果没有正确的构造SOAP消息,则无法正确交换服务的有效负载。

 SOAP Body提供了一种消息交换的机制,是SOAP消息的实际负载,可包含任意内容。SOAP消息体(SOAP Body)通过绑定服务调用方式(RPC或者Document)封装操作,绑定编码方式(Encoded或者Literal)序列化参数。SOAP消息的绑定样式由style、use和encodingStyle三个属性共同设置。style属性指定服务的调用方式,是采用RPC方式还是Document方式;use属性指定消息的编码方式,是采用Encoded方式还是采用Literal方式;而encodingStyle属性指定具体编码规则,例如可以指定SOAP编码规则、XML Schema编码规则等等,通常情况下都是采用XML Schema。

7.1style属性

        style属性描述了服务的调用方式,取值为”rpc”或者”document”,默认值为”document”。适用于SOAP Body元素的子元素(也可能是孙级元素)。此选项指定为WSDL文档中的soap:binding元素(通常情况下)或者soap:operation 的style属性。

A.RPC: 采用客户端/服务器方式(请求/响应),发送请求到服务器端,服务端执行方法后返回结果。优点是跨语言跨平台,缺点是编译时无法排错,只能在运行时检查。

SOAP消息本质上是一种从发送方到接收方的单向传输,但是SOAP经常组合到实现请求/响应机制中。要让RPC使用SOAP,必须遵循几条规则。首先,请求和响应消息必须被编码成结构类型。其次,对一个操作的每一个输入参数,都必须有一个同名元素(或输入结构的成员)作为参数。最后,对每一个输出参数,都必须有一个名称匹配的元素(或输出结构的成员)。

style=”rpc”指明遵从SOAP标准,在SOAP Body中封装RPC调用的请求和返回操作。对该类消息的约束是必须把操作的名称作为封装了对操作的请求和响应消息负载的根元素名称。对于SOAP请求消息,请求操作的名称是根据WSDL文档中的wsdl:operation元素命名,后者对应Web服务方法。对于SOAP响应消息,响应操作的名称是请求操作的名称后面追加"Response"构成。操作元素中的每个子元素表示一个参数,根据WSDL文档中的wsdl:part元素命名。RPC请求/响应消息的格式(省略了名称空间限定)如下:

RPC请求消息格式:

<SOAP信封>

<SOAP头部>

     ……

</SOAP头部>

    <SOAP消息体>

<请求操作名称>

          <参数名1>值</参数名1>

          <参数名2>值</参数名2>

             ......

        </请求操作名称>

</SOAP消息体>

</SOAP信封>

RPC响应消息格式:

<SOAP信封>

<SOAP头部>

  ……

</SOAP头部>

    <SOAP消息体>

       <响应操作名称>

          <参数名1>值</参数名1>

          <参数名2>值</参数名2>

              ......

        </响应操作名称>

    </SOAP消息体>

</SOAP信封>

B、Document与RPC相比较Document方式在XML文件中不是做远程方法的映射,而是一份完整的自包含的业务文档。当服务器端收到这份文档后,先进行预处理(比如词汇的翻译和映射),然后再构造出返回消息。构造返回消息的过程中,往往不再是简简单单的一个方法调用,而是多个对象协同完成一个事务的处理,再将结果返回。

 采用Document方式构造消息,SOAP Body元素中的内容完全由WSDL 中的 XML Schema定义,于是可以使用XML Schema验证SOAP Body元素中的内容。SOAP Body的子元素指定为消息部分在WSDL文档中定义的 wsdl:part 元素,该元素指向 XML Schema元素声明。通常wsdl:message不会包含多个wsdl:part 元素,所以SOAP Body 内容是真正的 XML 文档,尽管 WSDL 本身不禁止包含多个wsdl:part元素。Document请求/响应消息的格式(省略了名称空间限定)如下:

Document请求消息格式:

<SOAP信封>

<SOAP头部>

     ……

</SOAP头部>

    <SOAP消息体>

        <输入消息>

   ….

 </输入消息>

….

</SOAP消息体>

</SOAP信封>

Document响应消息格式:

<SOAP信封>

<SOAP头部>

 ……

</SOAP头部>

    <SOAP消息体>

         <输出消息>

   ….

  </输出消息>

….

    </SOAP消息体>

</SOAP信封>

7.2 use属性

 use属性描述了消息序列化的方式,取值为”encoded”或者”literal”,默认值是”literal”。 如果use=”encoded”,设置encodingStyle属性的值指定编码规则。如果use=”literal”,可以不用设置encodingStyle属性的值,通常情况都是使用默认的XML Schema。适用于出现在下一个级别的 Web 服务方法参数(或返回值)。此选项指定为WSDL文档中的 soap:body、soap:header、soap:fault和soap:headerfault元素的 use 属性。

A、Encoded,SOAP编码使用XML Schema的一个子集在XML文档与其所表示的数据之间进行绑定。SOAP 编码还使用href属性对文档中多次出现的元素的引用。SOAP编码和XML Schema编码完全不同的地方是数组。SOAP规范的5.4.2节指定了一种特别的机制来表示 XML 中的编程语言数组,它使用一种特殊的SOAP-ENC:Array类型。而XML Schema是通过设置element的minOccurs和maxOccurs属性值表示数组。例如使用这两种编码方式对整形数组的定义如下:

<complexType name="ArrayOfInt"> 
  <complexContent> 
     <restriction base="SOAP-ENC:Array"> 
<sequence>
    <element name=”item” type=”xsd:int” minOccurs=”0” maxOccurs=”unbounded”/>
</sequence>
        <attribute ref=" SOAP-ENC:arrayType"  wsdl:arrayType="xsd:ArrayOfInt[]"/> 
      </restriction> 
  </complexContent> 
</complexType>  

=================================================

//XML Schema定义数组
<complexType name="ArrayOfInt">  
<sequence>
 <element name=”item” type=”xsd:int” minOccurs=”0” maxOccurs=”unbounded”/>
</sequence>
  </complexContent> 
</complexType>

B、Literal与Encoded相比,Literal采用XML Schema编码,而不是SOAP编码;Literal编码不需要数据类型属性。数据根据 WSDL 文档中指定的 XML Schema定义或导入 WSDL 文档的 XML Schema定义逐字进行格式设置。使用Literal方式编码add方法的消息格式如下:

<op:add xmlns:op=”http://act.buaa.edu.cn/add”>
<a>
<item>45</item>
<item>36</item>
</a>
 <b>
<item>235</item>
<item>67</item>
</b>
</op:bdd>

7.3encodingStyle属性

        WSDL规范中的encodingStyle属性和SOAP规范中的encodingStyle 属性定义是一样的。encodingStyle属性的值是一个URIs列表,由单个空格隔开,每个URI代表着一种消息的编码规则,它们按照编码的限制从强到弱排序。encodingStyle属性是用来指定SOAP消息的编码规则,也就是序列化的格式和类型系统。如果use=”encoded”,encodingStyle属性的值为”http://schemas.xmlsoap.org/soap/encoding/”,则表示使用SOAP规范的第5节的编码,这一节定义了将编程语言的类型映射到 XML 的基本机制。如果use=”literal”则使用外部提供的类型系统,也可以通过encodingStyle属性来指定Schema,但是通常情况下使用XML Schema来编码SOAP消息。

    这其中的缘故是因为SOAP规范是在采用XML Schema规范之前编写的。因此,原始的SOAP规范必须提供一种方法来指明编码类型信息。然而,自从采用XML Schema之后,大多数语言使用自己的从XML Schema到编程语言类型之间的映射(或序列化规则),这使得SOAP编码变得过时。因此,推荐不要采用SOAP编码,而是采用使用Literal编码,在Literal映射中由 XML Schema 文档(通常是WSDL文档的形式)从外部指定映射。

========================================================================

8.SOAP消息构造

style和use属性都有两个值,通过它们之间的不同组合,就可以产生四种绑定样式,分别是rpc-literal、rpc-encoded、document-literal和document-encoded。为了使Document绑定样式能够支持RPC绑定样式的调用,增加了一种包装(Wrapped)样式,它只不过是对Document样式的使用进行了约束。这样就又增加了两种绑定样式, document-literal-wrapped和document-encoded-wrapped,一共合起来就有6种绑定样式。下面通过一个加法服务为例来说明在不同绑定样式下的SOAP消息构造,服务的定义如下:

从服务的定义可以看出,输入操作的操作名为add,有a和b两个整数类型的输入参数。根据WSDL规范返回操作的操作名应该为addResponse,有一个整数类型的输出参数,假设命名为return。

操作的序列化是需要名称空间限定的。如果是RPC调用方式,则名称空间是soap :body的namespace属性值;如果是Document调用方式,名称空间则是输入消息引用的Schema的targetNamespace属性值。参数的序列化是否需要名称空间限定取决于Schema定义时elementFormDefault属性的值。如果值为”qualified”则表示需要限定,名称空间为Schema的targetNamespace属性值;如果值为”unqualified”表示不用限定,默认值为”unqualified”。操作序列化后的元素作为SOAP消息体的子元素,而每个参数序列化后的元素都是作为操作元素的子元素,排列的顺序和操作的参数定义顺序一样。   

    A、如果use= ”encoded”则encodingStyle的值为”http://schemas.xmlsoap.org/soap/encoding/”,如果use= ”literal”则使用” http://www.w3.org/2001/XMLSchema”编码。

    B、如果style=”rpc”则wsdl:part 部分的类型引用使用type属性,如果style=”document”则使用element属性。

8.1 rpc-literal绑定样式

<wsdl:definitions xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/"
   xmlns:ns="http://act.buaa.edu.cn/add" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://act.buaa.edu.cn/add">
<wsdl:message name=”addRequest”>
 <wsdl:part name=”a” type=”xsd:int”/>
    <wsdl:part name=”b” type=”xsd:int ”/>
</wsdl:message>
<wsdl:message name=”addReponse”>
    <wsdl:part name=”return” type=”xsd:int”/>
</wsdl:message>
<!--Just assume it's rpc-literal. -->
......

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Body>
     <op: add  xmlns:op=“http://act.buaa.edu.cn/add”>
       <a>12</a>
<b>45</b>
     </op: add >
   </env:Body>
</env:Envelope>]

 优点:WSDL 描述和SOAP消息基本达到了尽可能地简单易懂的要求;服务的操作名出现在SOAP消息的Body中,这样接收者就可以很轻松地把消息发送到方法的实现;没有类型编码,提高了吞吐量,减少了处理的性能开销。

    缺点:在RPC模型中XML仅仅被用于描述方法的信息,不能充分利用XML的功能去描述和验证一份业务文档 ;不能使用Schema简单地检验此消息的有效性,因为只有参数a和b是Schema 中定义的内容,其余的 env:body 内容(例如add元素)都来自 WSDL 定义;无法直接从消息中获得参数的类型信息;RPC样式对请求/响应消息的模式捆绑,使得服务与客户端之间耦合性增加,一旦方法发生变化,客户端就需要做相应的改动;相对异步调用方式而言,RPC样式下服务调用通常是同步的。

8.2 rpc-encoded 绑定样式

<env:Envelope  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi=” http://www.w3.org/2001/XMLSchema-instance” >
  <env:Body>
     <op: add xmlns:op=“http://act.buaa.edu.cn/add”>
        < a  xsi:type=”xsd:int”>12</a>
<b  xsi:type=”xsd:int”>45</b>
     </op: add >
   </env:Body>
</env:Envelope>

 与rpc-literal绑定样式唯一的区别就是请求消息的参数部分编码方式不一样。消息中的每个参数都有类型编码(比如 <a xsi:type=”int”>12</a>),直接从消息就可以知道参数的数据类型。但是这些类型信息降低了吞吐量和消息处理的性能。尤其是在大数据的情况下,性能开销明显。

 rpc-encoded绑定样式主要在重载、数据图形和多态的情况下使用。WSDL 允许重载的操作,但是当参数个数相同的情况下,因为Literal编码方式没有类型信息,无法定位方法,所以rpc-literal就不支持这样的重载。数据图形的标准方式是使用href 标记,它是 rpc-encoded的样式。多态所生成的 SOAP 消息必须包含类型编码信息,这样接收终端才能知道它所接收的是父类的哪一个扩展。

8.3 document /literal绑定样式

<wsdl:definitions xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/"
xmlns:ns="http://act.buaa.edu.cn/add" targetNamespace=" http://act.buaa.edu.cn/add ">
<wsdl :types>
<xs:schema elementFormDefault="qualified" targetNamespace="http://act.buaa.edu.cn/add" xmlns:xs="http://www.w3.org/2001/XMLSchema" >  
       <xs:element name="a"  type="xs:int " />
       <xs:element name="b"  type="xs:int " />
       <xs:element name="return"  type="xs:int " />
</xs :schema>
</wsdl :types>
<wsdl:message name=”addRequest”>
     <wsdl:part  name=”parameter1” element=”ns:a”/>
<wsdl:part  name=”parameter2” element=”ns:b”/>
</wsdl:message>
<wsdl:message name=”addReponse”>
     <wsdl:part name=”parameter” element=”ns:return”/>
</wsdl:message>
<!--Just assume it's  document-literal. -->
……

================================================================
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:op=“http://act.buaa.edu.cn/add”>
<env:Body>
    <op:a>12</op:a>
<op:b>45</op:b>
</env:Body>
</env:Envelope>

请求消息的参数元素添加了名称空间限定,这是因为输入消息在WSDL文档的Schema中定义,而且Schema的elementFormDefault=”qualified”。也就是说参数元素必须使用Schema的名称空间"http://act.buaa.edu.cn/add"进行限定。

 优点:没有操作和类型编码信息,减少了消息的数据量,提高了消息处理性能;env:Body中每项内容都定义在Schema中,可以用任何XML检验器检验此消息的有效性。

 缺点:WSDL文档变得比较复杂,这不过是一个非常小的缺点,因为 WSDL 并没有打算由人来读取;SOAP消息中没有提供服务操作的名称,一些特定的程序代码在分发消息时可能会变得复杂,并且有时变得不可能。如果使用HTTP作为底层传输协议,可以使用SOAPAction属性绑定操作的名称来解决消息分发的问题。虽然大多数情况下都是使用HTTP协议来传输SOAP消息,但是这种方法绑定了底层传输协议,限制了其他传输协议的使用。

8.4 document /encoded绑定样式

<env:Envelope  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi=” http://www.w3.org/2001/XMLSchema-instance”
       xmlns:op=“http://act.buaa.edu.cn/add”>
   <env:Body>
       <op:a  xsi:type=”xsd:int”>12</op:a>
<op:b  xsi:type=”xsd:int”>45</op:b>
   </env:Body>
</env:Envelope>

 与document-literal绑定样式唯一的区别就是请求消息的参数部分编码方式不一样。引入了类型编码,降低了吞吐量和消息处理的性能。这种绑定样式不被大多数Web服务实现平台支持。

8.5  document-literal-wrapped绑定样式

<wsdl:definitions  xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/"
xmlns:ns="http://act.buaa.edu.cn/add"  targetNamespace=" http://act.buaa.edu.cn/add ">
<wsdl :types>
<xs:schema elementFormDefault="qualified" targetNamespace="http://act.buaa.edu.cn/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" >  
       <xs:element name="add">
          <xs:complexType>
            <xs:sequence>
               <xs:element name="a"  type="xs:int " />
               <xs:element name="b"  type="xs:int " />
            </xs:sequence>
          </xs:complexType>
       </xs:element>
       <xs:element name="addResponse">
          <xs:complexType>
            <xs:sequence>
               <xs:element name="return"  type="xs:int " />
            </xs:sequence>
         </xs:complexType>
       </xs:element>
</xs :schema>
</wsdl :types>
<wsdl:message name=”addRequest”>
    <wsdl:part  name=”parameter” element=”ns:add”/>
</wsdl:message>
<wsdl:message name=”addReponse”>
    <wsdl:part name=”parameter” element=”ns:addResponse”/>
</wsdl:message>
<!--Just assume it's  document-literal-wrapped. -->
……
=====================================================================
<env:Envelope  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
   <env:Body>
     <op: add  xmlns:op=“http://act.buaa.edu.cn/add”>
       <op:a>12</op:a>
<op:b>45</op:b>
     </op: add >
  </env:Body>
</env:Envelope>

此时SOAP Body中第一个元素的名称并不是操作的名称,而是Schema中的元素的名称。Schema中的元素的名称可以与操作名相同,也可以不同。如果取相同则是一种将操作名放入SOAP消息的巧妙方式。

  虽然此SOAP 消息看起来与 rpc-literal的 SOAP 消息是完全一样的(如果不考虑名称空间限定),但是这两种消息之间存在着微妙的区别。在 rpc-literal的 SOAP 消息中,<env:Body>下的<op:add>根元素是操作的名称。在document-literal-wrapped的SOAP 消息中,<op:add>元素是单个输入消息的组成部分引用的元素的名称。

 document-literal-wrapped样式规定Document绑定操作的输入消息和输出消息都只有一个wsdl:part部分;该部分使用element属性引用一个元素;该元素是复杂类型并且没有属性;该元素的名称和操作的名称必须一样。

 优点:包装行为吸取了RPC样式的一个重要优点,即RPC样式中SOAP消息体可以直接通过与之关联的服务操作名称来命名,同时又摒弃了RPC样式的不足之处;可以利用WSDL文档类型部分的Schema文档直接来验证SOAP消息体;只要在Schema中定义了明确的数据结构,如何构建SOAP消息体具有很大的灵活性;由于业务数据是自包含的,显然文档模型更利于采用异步处理。

 缺点:WSDL 较为复杂, 但是这仍然是一个非常小的缺点。使得服务调用的复杂度有所增加,尤其是在API级别。针对程序开发人员来说,基于包装的document绑定样式的服务编写客户端代码也许就变成了一项极具挑战性的工作。在SOAP消息体的XML包装元素中必须拥有一个服务操作的名称,因此包装版本不支持重载的服务操作。实际上,针对一个既定的元素名称也只能够有一个服务操作。

8.6 document-encoded-wrapped绑定样式

<env:Envelope  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi=” http://www.w3.org/2001/XMLSchema-instance” >
  <env:Body>
     <op: add  xmlns:op=“http://act.buaa.edu.cn/add”>
        <op:a  xsi:type=”xsd:int”>12</op:a>
<op:b  xsi:type=”xsd:int”>45</op:b>
     </op: add >
   </env:Body>
</env:Envelope>

与document -literal-wrapped绑定样式唯一的区别就是请求消息的参数部分编码方式不一样。引入了类型编码,降低了吞吐量和消息处理的性能。

========================================================================

9.SOAP 附件

实际应用中需要和各种附件(如图像、图画、xml 文档等)一起发送SOAP消息。附件数据通常是特殊的二进制格式。 带附件的SOAP规范详细说明了使用“MIME multipart/related” 媒体类型和URI模式引用MIME部件。并不是所有的Web服务工具箱都提供SOAP附件支持。Microsoft提出了另一个基于DIME的附件解决方案

9.1 SOAP消息包

带附件的SOAP消息包如下 ,SOAP消息包包含XML格式的主SOAP消息以及SOAP信封中未定义但与消息有关的任意数据格式(例如 gif、jpg 和 xml 等)的其它实体。

SOAP消息包是用MIME的Multipart/related 媒体类型构建的,每个部件都嵌入MIME边界(在Context-Type报头中定义)。每个 MIME部件都有报头信息比如Context-Type 它指定嵌入这MIME部件的数据的类型)、Content Transfer-encoding(指定用于这个MIME部件的编码)、 Content-ID或Content-Location(作为从MIME包的任何地方引用这些内容的标识符)。MIME消息的根部件包含SOAP信封,Content-Type被设置为text/xml。

9.2 SOAP对附件的引用

SOAP报头和SOAP消息的主体都可以引用消息包中的其它实体。根据 SOAP 1.1 编码规则,SOAP的“href”属性可用于引用任何资源。任何资源都可以使用Content-ID或者Content-Location引用。如果使用Content-ID作为标识符,那么模式属性(例如href)必须使用URL模式CID。如果使用Content-Location作为标识符,那么必须根据 带附件的 SOAP规范中指定的规则进行解析,其中解析是基于下列要素之一:

绝对URI引用 ― 绝对URI是SOAP信封中的Content-Location和“href”属性中指定的。相对URI引用― MIME消息主报头的Content-Location中指定了一个基础(base)URI,对所有的相对URL都是使用这个基础URL进行引用.不带基础URI的相对URI ― 主报头的Content-Location中没指定基础URI,但使用消息的基础URL,并且对所有的相对URL都是使用这个基础URL进行引用。

通常由SOAP处理器决定是否需要解析URI。而且,消息包中可能有在SOAP信封中没有URI引用的附件。

9.3 HTTP绑定

如果HTTP绑定被SOAP用来发送附件,就需要修改HTTP报头使其包含来自SOAP MIME包报头的Content-Type信息。HTTP报头中不包含来自MIME包报头的其它报头信息。Apache忽略了报头信息比如Content-Transfer-Encoding和MIME Version 。所有的MIME部件都包含SOAP信封部件和其它附件,构成HTTP主体。另一方面,对于 SMTP绑定来说,所有的多部件MIME报头都会被作为SMTP报头的一部分存储。这样,SOAP处理器和应用程序就应该知道这些报头与不同种类的 SOAP 绑定的不兼容性。

9.4 WSDL支持

WSDL支持描述带附件的Web服务。

<binding name="DocManagementService_Binding"  ... />
  <operation  name="SubmitArrayOfDocuments">
    <soap:operation soapAction="http://www.DocManagementService.com/SubmitArrayOfData"/>
    <input>
      <mime:multipartRelated>
          <mime:part>
            <soap:body
    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    namespace="urn:DocManagement-service"
    parts="SubmitArrayOfDocuments_inType1 SubmitArrayOfDocuments_inType2"
    use="encoded"/>
          </mime:part>
          <mime:part>
            <mime:content part="SubmitArrayOfDocuments_inType3" type="*/*"/>
          </mime:part>
    </mime:multipartRelated>
    </input>
    <output>
      <soap:body
    encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    namespace="urn:DocManagement-service" 
    use="encoded"/>
    </output>
  </operation>
</binding>

binding元素的input和output元素被扩展,并且包含了带有不同MIME部件的MIME:multipart-related,其中一个MIME部件用于 SOAP主体,其它的用于附件。每个带附件的MIME部件也都可以指定其内容类型。

========================================================================

SOAP协议示例

SOAP 1.2 请求和响应示例。所显示的占位符需替换为实际值。

//SOAP 1.2 请求
POST /WebServices/WeatherWS.asmx HTTP/1.1
Host: ws.webxml.com.cn
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <getWeather xmlns="http://WebXml.com.cn/">
      <theCityCode>string</theCityCode>
      <theUserID>string</theUserID>
    </getWeather>
  </soap12:Body>
</soap12:Envelope>


//SOAP 1.2 响应
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <getWeatherResponse xmlns="http://WebXml.com.cn/">
      <getWeatherResult>
        <string>string</string>
        <string>string</string>
      </getWeatherResult>
    </getWeatherResponse>
  </soap12:Body>
</soap12:Envelope>

 HTTP GET 请求和响应示例。所显示的占位符需替换为实际值。

GET /WebServices/WeatherWS.asmx/getWeather?theCityCode=string&theUserID=string HTTP/1.1
Host: ws.webxml.com.cn
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns="http://WebXml.com.cn/">
  <string>string</string>
  <string>string</string>
</ArrayOfString>

 HTTP POST 请求和响应示例。所显示的占位符需替换为实际值。

POST /WebServices/WeatherWS.asmx/getWeather HTTP/1.1
Host: ws.webxml.com.cn
Content-Type: application/x-www-form-urlencoded
Content-Length: length

theCityCode=string&theUserID=string
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns="http://WebXml.com.cn/">
  <string>string</string>
  <string>string</string>
</ArrayOfString>

 参考文章

​​​​​​SOAP协议解析_tuowsh的博客-CSDN博客​​​​​​

 WeatherWS Web 服务

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SOAP传输协议 的相关文章

  • 使用 Java 将包含 XML 的字符串添加到 SOAPElement

    我必须将 Excel 文件中的数据作为 XML 发送到 Web 服务 表中的数据看起来有点像这样 请参阅此处的表格示例 https i stack imgur com NEOTi png 第一行始终包含该列数据的 XML 标记 大多数数据列
  • 使用 Python 请求发送 SOAP 请求

    是否可以使用Python的requests http docs python requests org en master 库发送 SOAP 请求 这确实是可能的 以下是使用普通请求库调用天气 SOAP 服务的示例 import reque
  • 如何使用ipad的objective-c发送/接收soap对象

    我一直在尝试为 ipad 编写一个 Objective C 应用程序来发送 接收肥皂网络服务 我已经写了一个代码 但它给出了一个错误 网络服务正在在线运行 这是我的代码 IBAction invokeService txt1 resignF
  • PHP NuSoap 中的复杂类型

    我正在使用 PHP 中的 NuSoap 库构建一个 Web 服务 我的 Web 服务将充当客户端和供应商现有的 Web 服务之间的中间层 因此 客户端不是直接连接到供应商 而是连接到我的 Web 服务 我的 Web 服务连接到供应商并获取响
  • Visual Studio/SOAP -“添加服务引用”与“添加 Web 服务引用”

    我发现我可以将计划使用的 SOAP WSDL 服务作为 Web 服务引用 System Web Services 或 服务引用 System ServiceModel WCF 导入到我的解决方案中 我想知道有什么区别 据我所知 添加服务引用
  • 使用 JAX-WS 的 SOAP 消息中的嵌套标记中没有命名空间

    我正在尝试使用 JAX WS 和 wsimport 编写一个使用给定 Web 服务的 Java 应用程序 它发送到服务的 SOAP 消息大部分是正确的 然而 传递给服务函数的参数之一是字符串数组 尽管在 SOAP XML 中为数组本身指定了
  • 带有 WCF BadContextToken 的 PHP Soap 客户端

    经过几天的谷歌 in 尝试 脱发 我仍然找不到解决方案 所以请帮助 简短信息 我需要使用 PHP SOAP 客户端 的 WCF 服务 它使用 wsHttpBinding ws security 并且无法设置 basicHttpBinding
  • PHP Soap Server:使用字符串(xml 字符串)而不是 WSDL 文件(指向它的 url)实例化

    Soap Server的PHP页面 我见过 http www php net manual en soapserver soapserver php http www php net manual en soapserver soapser
  • 在 iPhone 中使用 Soap Web 服务与 wsdl2objc?

    我确实意识到这是一个重复的问题 但是唯一的其他问题已经很老了 所以我想知道是否有人最近有过使用最新版本的经验wsdl2objc http code google com p wsdl2objc 我正在编写一个应用程序 该应用程序将与第三方应
  • 来自本地 XML 的模拟 SoapClient 响应

    我想用文件中的 XML 来模拟 SoapClient 的响应 我如何创建一个 stdClass 对象 就像 SoapClient 从文件返回一样 客户端已经包装了 SoapClient 因此可以轻松模拟响应 我的模拟是这样的 soapCli
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • Oracle Service Bus 中如何使用 WSDL?

    我使用 WSDL 创建了一个 OSB 服务并选择了一个绑定 现在 当我的客户尝试使用我提供的 WSDL 调用服务时 他们会收到错误 另外 我提供的 WSDL 中的绑定名称和他们从 URL 中提取的 WSDL 是不同的 怎么了 根据 OSB
  • 使用 SOAP 调用 WCF 服务

    我正在尝试在不创建 WCF 客户端的情况下测试 WCF 服务 我有类似的代码 问题here https stackoverflow com a 1643025 1397017 我希望完全控制 SOAP 负载 因此我希望能够发出我自己的 We
  • WSDL 中的数组响应 - SOAP PHP

    在我的 wsdl 代码中 我得到一个整数 我想返回数组中的结果 为什么在我的输入中我只有一个整数 而我需要数组中的结果 因为在我的 php 函数中 我想从客户端选择的整数中的数据库返回信息 例如 我的客户发送1 在我的php中 我从数据库中
  • 如何在 ColdFusion 中对 SOAP 请求正文进行数字签名?

    对我来说是新的挑战 我需要使用提供商颁发的证书对来自 ColdFusion 客户端应用程序的 SOAP 请求正文进行数字签名和加密 我还需要解密响应才能处理它 我已经搜索了几天 但一无所获 我找到了引用其他语言的信息 但在 ColdFusi
  • IIS 上托管的 WCF 服务无法运行

    我想构建一个公开 basicHTTP 端点和 webHTTP 端点的服务 如果我在运行模式下使用 VS2010 测试以下项目 一切都很好 但我想在 IIS 中托管服务 本地或远程 并通过测试 服务 svc 我将我的网站托管到本地 IIS 中
  • 如何在 Perl 中发送此 SOAP XML?

    我必须发送下面的 XML 我有no idea从哪儿开始 我知道我需要在 Perl 中查找 SOAP 但大致就是这样
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 捕获传入和传出的肥皂请求

    我有一个 C 控制台应用程序 它调用基于 SSRS Soap 的 Web 服务 服务在远程计算机上运行 我想捕获传入和传出的肥皂请求 如何才能做到这一点 Thanks 这只是为了调试目的吗 如果是这样 Fiddler http www fi
  • 肥皂服务的良好框架是什么?

    我正在寻找一个用于肥皂的好框架service 我更喜欢使用Pythonic框架 但是在查看了soaplib rpclib 太不稳定 SOAPy 不适用于2 7 和ZSI 太 令人困惑 之后 我不确定这是否可能 我对使用另一种语言感到满意 尽

随机推荐

  • fatal: unable to access ‘https://github.com/sohee-lee7/Squire.git/‘:

    解决方法 xff1a 执行 git config global url 34 git 34 insteadOf https
  • C语言中常见的两个比较字符串是否相等的函数strcmp和strncmp

    函数 xff1a strcmp和strncmp strcmp 使用格式 xff1a include lt string h gt int strcmp const char s1 const char s2 设这两个字符串为str1 xff
  • sprintf和printf 用法的区别

    printf 的作用是标准化输出 xff0c 默认的对象是标准输出缓冲区 xff0c 要有一定的条件才能把缓冲区里面的数据输出 sprintf 作用是格式化输出函数 xff0c 保存字符串到缓冲区中 xff0c 起到拼接字符串的作用 功能
  • select函数实现TCP双向通信

    服务器通信实现代码 include 34 myhead h 34 tcp双向通信 服务器的代码 多路复用使用思路 xff1a 1 思考要监测什么文件描述符 新的套接字 接收 键盘 发生 2 监测新套接字的读就绪 监测键盘的读就绪 int m
  • C++调用构造函数,后面用冒号添加变量的作用

    C 43 43 调用构造函数和成员函数后 xff0c 在函数的后面添加一个冒号的含义 首先知道初始化机制中 xff0c 有两种赋值机制 xff0c 有赋值运算符赋值和括号赋值 xff1a 传统赋值 xff1a int a 61 10 int
  • 第六篇,STM32脉冲宽度调制(PWM)编程

    1 PWM概念 PWM叫脉冲宽度调制 Pulse Width Modulation xff0c 通过编程控制输出方波的频率和占空比 高低电平的比例 xff0c 广泛应用在测量 xff0c 通信 xff0c 功率控制等领域 呼吸灯 xff0c
  • ovn 配置逻辑路由器实现三层转发

    本文使用ovn搭建一个三层转发的环境 xff0c 拓扑图如下 image png 两个虚拟交换机ls1和ls2 xff0c 端口ip网段分别为 10 10 10 0 24和 10 10 20 0 24 虚拟交换机上分别连接两个vm 使用na
  • 第十篇,STM32串口蓝牙编程

    1 串口蓝牙概念 串口蓝牙是一个蓝牙模块 xff0c 内部有蓝牙模块和程序 xff0c 可以进行蓝牙通信 xff0c 同时提供一个串口接口 xff0c 通过串口可以配置蓝牙模块进行数据传输 2 使用串口3连接蓝牙模块 3 手机上安装蓝牙调试
  • 第十四篇,STM32的CAN总线通信

    1 CAN总线的概念 CAN指的是控制器局域网网络 Controller Area Network xff0c 由德国博世汽车电子厂商开发出来 CAN使用差分信号 xff0c 具有较强的抗干扰能力和传输稳定性 CAN属于多主通信 xff0c
  • OpenCV图像处理学习十九,像素重映射cv::remap

    一 像素重映射概念 重映射就是把输入图像中各个像素按照制定的规则顺序映射到另外一张图像的对应位置上去 xff0c 形成一张新的图像 二 像素映射API函数接口 cv remap xff08 InputArray src 输入图像 Outpu
  • OpenCV图像处理学习二十一,直方图比较方法

    一 直方图比较 直方图比较是对输入的两张图像进行计算得到直方图H1与H2 xff0c 归一化到相同的尺度空间 xff0c 然后可以通过计算H1与H2的之间的距离得到两个直方图的相似程度 xff08 每张图像都有唯一的直方图与之对应 xff0
  • 嵌入式FreeRTOS学习八,xTaskCreate创建任务的细节以及恢复中断任务实现

    一 创建任务函数xTaskCreate 任务也不是很复杂的东西 xff0c 任务也就是一个函数xTaskCreate 简单得说 xff0c 创建一个任务 xff0c 你得提供它的执行函数 xff0c 你得提供它的栈的大小 xff0c 函数的
  • 嵌入式FreeRTOS学习一,FreeRTOS概述和代码结构

    一 FreeRTOS是什么 FreeRTOS 是由 Real Time Engineers Ltd 出品 xff0c 是一款市场领先的 RTOS 现在已经支持几十种 处理器架构 Free即免费的 xff0c RTOS全称是 Real Tim
  • 嵌入式FreeRTOS学习二,FreeRTOS任务的创建和删除

    一 任务的创建和删除 1 1 函数xTaskCreate 此函数用来创建一个任务 xff0c 任务需要RAM来保存与任务有关的状态信息 任务控制块 xff0c 任务也需要一定的RAM 来作为任务堆栈 如果使用函数xTaskCreate 来创
  • 嵌入式FreeRTOS学习五,FreeRTOS任务调度器

    四 调度器 FreeRTOS 操作系统支持三种调度方式 xff1a 抢占式调度 xff0c 时间片调度和合作式调度 实际应用主要是抢占式调度和时间片调度 xff0c 合作式调度用到的很少 启动调度器的API函数vTaskStartSched
  • 嵌入式FreeRTOS学习九,任务链表的构成,TICK时间中断和任务状态切换调度

    一 tskTaskControlBlock 函数结构体 在tskTaskControlBlock 任务控制块结构体中 xff0c 其中有任务状态链表和事件链表两个链表成员 xff0c 首先介绍任务状态链表这个结构 xff0c 这个链表通常用
  • 嵌入式FreeRTOS学习十,任务调度和任务就绪链表任务调度过程

    一 main函数里面的栈是哪里分配的 main函数里面用到的栈 xff0c 假设为msp 是汇编代码里面设定的 xff0c 对于STM32F103 在汇编代码里的向量表设置了一个栈 initial sp 那这个栈是给谁用的呢 xff1f 可
  • ovn 通过网关虚拟路由器连接外部网络

    本文实验如何通过ovn的网关逻辑路由器将ovn网络连接到外部网络 前面讲过ovn的逻辑路由器是分布式的 xff0c 这意味着它没有绑定到某个节点上 xff0c 而是存在于所有节点上的 xff0c 同时它是通过每个节点的openflow流表来
  • 嵌入式FreeRTOS学习十一,深入理解任务调度机制

    一 任务调度机制 可抢占 xff1a 高优先级的任务先运行时间片轮转 xff1a 同优先级的任务轮流执行空闲任务礼让 xff1a 如果有同是优先级为0的其他就绪任务 xff0c 空闲任务主动放弃一次运行机会函数调用vTaskDelay xD
  • SOAP传输协议

    一 HTTP传输协议 超文本传输协议 xff08 HyperText Transfer Protocol xff0c 缩写 xff1a HTTP xff09 xff0c 它是基于请求 响应的模式协议 xff0c 客户端发出请求 xff0c