3.5 SOAP消息解剖
SOAP规范描述了四个主要的构件.使用信封形式的封装数据和路由路径的格式化规范,传输或是绑定协议,编码规则,RPC调用机制 . 信封定义一个为描述消息内容的规范,这个消息有一种轮流排队处理的含义.协议绑定能够使用低级别的HTTP协议传递SOAP消息提供一个一般的机制.编码规则提够一种规范为了映射各种各样应用数据到基于标签表现的TAG。最后 RPC机制提够了一种表示远程调用和他们返回值的方法。 众览这本。我们将涉及到这四个共有方面作为一种SOAP消息.
3.5.1 如何将XML转变成SOAP
我们通过关注文档交换模型来开始这个讨论.为了讲清楚这个话题,我们使用简单的购置订单文档.po.xml . 这个文档是简单的,因为他包括两件事,一件是运送地址,一件是明细实体。
<?xml version=”1.0” encoding=”UTF-8”?>
<PurchaseOrder xmlns =”urn:oreilly-yaws-samples”>
<shipTo country=”US”>
<name>jeo simth</name>
<street>14 oak park</street>
<city>bedford</city>
<state>MA</state>
<zip>01730</zip>
<shipTo>
<items>
<item partNum =”872-AA”>
<productName>candy cense</productName>
<quantity>444</quantity>
<price>1.68</price>
<comment>I want candy!</comment>
</item>
</items>
</purchanseOrder>
PO.XML 还不是一个SOAP文档,他仅仅是一个香草的XML文档。怎么样才能是他编程一个SOAP文档
l 在SOAP体的内部包装XML
l 在一个信封里面包装SOAP体
l 有选择的包含SOAP头
l 命名空间声明
l 为了数据序列化的编码风格。
l 绑定整个件事情到协议
一个SOAPenvelope 包括两个私有组件,一个是header,一个是body 在header和body可以包含很多信息块。
下面的列出的被envelope包裹的po.xml 使他成为一个soap。
<?xml version=’1.0’ encoding=’UTF-8’?>
<SOAP-ENV: Envelope
xmlns : SOAP-ENV=http://schema.xmlsoap.org/soap/envelope
xmlns :xsi =http://www.w3.org/1999/XMLschema-instance
xmlns : xsd=http://www.w3.org/19999/XMlSchema>
<SOAP-ENV :Header>
…………………..
</SOAP-ENV:Header>
<SOAP-ENV:BODY>
<?xml version=”1.0” encoding=”UTF-8”?>
<PurchaseOrder xmlns =”urn:oreilly-yaws-samples”>
<shipTo country=”US”>
<name>jeo simth</name>
<street>14 oak park</street>
<city>bedford</city>
<state>MA</state>
<zip>01730</zip>
<shipTo>
<items>
<item partNum =”872-AA”>
<productName>candy cense</productName>
<quantity>444</quantity>
<price>1.68</price>
<comment>I want candy!</comment>
</item>
</items>
</purchanseOrder>
</SOAP-ENV:BODY>
</SOAP-ENV: Envelope>
3.5.2 THE SOAP ENVELOPE
SOAP envelope 是勾画出SOAP文档的最远X,ML标签.下面的信封标签展示了三个必须的属性,即指定的命名空间,和为envelope使用的schema
<SOAP-ENV: Envelope
xmlns : SOAP-ENV=http://schema.xmlsoap.org/soap/envelope
xmlns :xsi =http://www.w3.org/1999/XMLschema-instance
xmlns : xsd=http://www.w3.org/19999/XMlSchema>
下面解释这个标签的语法。 第一个属性xmlns : SOAP-ENV=http://schema.xmlsoap.org/soap/envelope 是一个命名空间的声明。命名空间的声明阻止标签名字的冲突,当 XML碎被组成一个混合的文档的时候,,我和他JAVA里面使用包关键字是想同的.
首先,你可能看到<SOAP-ENV: Envelope xmlns : SOAP-ENV 除非了是一个特定的关键字之外就没什么了。事实上 初了使用 SOAP-ENV ,Envelope 和xmlns 完全就是主观的.在关键字中,Envelope 和xmlns,是重要的. URL http://schema.xmlsoap.org/soap/envelope 是一个被SOAP定义的保留的名字空间的URI。在我们的生活中是唯一的字符串.通用的习惯就是使用URI代替住址或是个人拥有的URL。这样的规范确保URI是一个全球唯一,他看起来是这样的:
<abbr: Envelope
xmlns : abbr=http://schema.xmlsoap.org/soap/envelope
xmlns :xsi =http://www.w3.org/1999/XMLschema-instance
xmlns : xsd=http://www.w3.org/19999/XMlSchema>
……….
</ abbr: Envelope >
在这个版本中的信封元素xmlns:abbr 声明了一个缩写的元素用来代替http://schema.xmlsoap.org/soap/envelope/.标签<abbr: Envelope ......和</ abbr: Envelope >暗示出这个命名空间的范围是整个信封.
紧接着 xmlns :xsi =http://www.w3.org/1999/XMLschema-instance 属性 声明了XML模式的实例空间.前缀XSI必须被放到所有被在命名空间元素和属性的前面. 对于一个属性的例子是xsi:type 它指定元素的类型是为了编码目的.
最后xmlns : xsd=http://www.w3.org/19999/XMlSchema 是另一个命名空间的声明 和xsi 和SOAP-EVN 相似。这个声明定义了XML模式的命名空间。来自己命名空间的元素被当作一个xsi:type属性的值。例如,xsd:string 或 xsd:boolean..对于SOAP文档的模式不会指向SOAP 信封.
3.5..3 SOAP 头
Soap 头和体在语法上面是相似的。SOAP1.1 和SOAP1.2 没规范说在头中需要什么。SOAP 头是一个简单的放指令到接收消息的SOAP处理器的地方。发送和接收消息的地方要就元素到什么地方和代表什么意思达成一致。建立在SOAP之上的比较高级的协议,比如EBXML MESSAGE SERVICE (MS)已经规则话的使用被定义特定元素的诸如<MessageHeader>SOAP 头.在<MessageHeader>包含指定的标签<from>,<to>,<MessageId> SOAP体被希望真实的数据 或是消息净负荷 希望被最后的接收者消费和处理
当使用SOAP 进行远程调用的时候,头和体的区别是简单的。<body.> 被纯作为方法和参数的调用,头是被作为事情最基础的部分 ,比如一个事物ID。事物ID不能被属于一个方法的签名 ,他被打算为SOAP处理器接收消息,这个消息为J2EE服务提供事务处理。
这里有一个SOAP头的事例:
<SOAP-ENV: Envelope
xmlns : SOAP-ENV=http://schema.xmlsoap.org/soap/envelope
xmlns :xsi =http://www.w3.org/1999/XMLschema-instance
xmlns : xsd=http://www.w3.org/19999/XMlSchema>
<SOAP-ENV:Header>
<jaws:MessageHeader xmlns:java=”urn:oreilly-jaws-sample”>
<From>Me</From>
<To>You</To>
<MessageId>9999</MessageId>
</jaw:MessageHeader>
</SOAP-ENV:Header>
<SOAP-EVN:Body>
……………………..
<SOAP-EVN:Body>
</SOAP-ENV: Envelope>
3.5.4 SOAP协议绑定
在这点上,我们仅仅需要增加一件事情,使PO.XML进到SOAP消息里面去:soap消息需要被协议绑定。 当他被绑定到HTTP协议上的时候,下面的列表显示了HTTP头信息 :
SOAPAction =”urn : soaphttpclient-action-uri”
Host = localhost
Content-Type=text/xml;charset=utf-8
Content-Length=701
<?xml version=’1.0’ encoding=’UTF-8’?>
<SOAP-ENV : Envelope
Xmlns : SOAP-ENV =http://schemas..xmlsoap.org/soap/envelop/
Xmlns : xsi= http://www.w3.org.1999/XMLSchema-instance
Xmlns: xsi =www.w3.org/1999/XMLSchema>
……………………..
</SOAP-EVN:Envelope>
SOAPAction 头稍微有一点改变.在SOAP1.1中,他是HTTP协议的绑定的需要.他的意图是允许路由或是调度这类事情不需要SOAP知识或是不需要解析SOAP信封就能做的很好。比较,一些CGI脚本或是以路由请求为目的的SERVLET 不必处理SOAP信封就能拿到路由信息,这个概念是伟大的,但是他要绑定HTTP协议。
在soap1.2 SOAPAction 已经被优化了..他不取决把扩展强加到一个基础的协议.在这种情况下,对于诸如Action的HTTP请求头的存在,或是创造一个叫做SOAPAction 的东西就不能归咎于任何人。我们确实需要一种生成机制为了独立于协议的指定的带数据。如果如此的一件事情存在,人们只为创建一个标准的到HTTP隐射负责,这个HTTP可能也已经包含有一个SOAPAction 头。但是,对于映射的第一种语义不应该指定射影余下的 部分应该咋样做。