级别: 初级 柴晓路 (fennivel@dealeasy.com)Chief Solution Architect
2002 年 7 月 01 日 本文承继前一篇SOAP绑定框架,应用SOAP绑定框架来描述一个最基本的SOAP交互模式:单一请求/响应传输消息交换模式。在该模式下,服务方接收调用方的调用SOAP消息,然后向调用方发送响应SOAP消息。本文的主要目的是给出一个应用SOAP绑定框架来描述绑定规范的实例,为用户以后自行定义提供属性和状态转移描述相关定义的实践。
SOAP的传输无关性使得SOAP消息可以方便地和任意的通信协议进行绑定,比如SMTP、FTP都是可能的绑定协议,事实上,从原则上说,任意的用于传输信息的网络协议都可以与SOAP进行绑定。在实际的绑定中,一般而言SOAP总是依附于这些传输网络协议的自身语义,依靠这些传输网络协议的交互模式,表达SOAP所需要表达的传输消息交换模式。这样的传输消息交换模式一般包括四种:
- 单向 (One-Way):服务方单方面接收SOAP消息。(比如简单的数据接受服务)
- 请求响应 (Request-Response):服务方接收调用方的调用SOAP消息,然后向调用方发送响应SOAP消息。(通常的服务调用)
- 要求响应 (Solicit-Response):服务方向使用者发送SOAP消息,然后接收使用者的响应SOAP消息。(比如定时通知服务,并且对于重要通知要求用户给出回执)
- 通知 (Notification):服务方单方面发送SOAP消息。
一般来说,传输协议的交互方式总是涵盖了这些调用交互模式的,对于SOAP消息而言,SOAP消息的传送是依靠传输协议的传输具体数据的那部分来完成的。也就是说传输协议的控制部分完成交互模式,而传输协议的数据部分传送SOAP消息。
在下面,我们以请求响应为例,讨论如何描述传输消息交换模式。
传输消息交换模式概述
本节介绍的传输消息交换模式(TMEP,Transport Message Exchange Pattern)是一个消息交换的模版,试用于由一个或多个传输绑定实例所支持的SOAP结点间的消息交换。
通常,一个传输消息交换模式的定义包括:
- 描述了与该模式相一致的传输消息交换的生命周期;
- 描述了与该模式相一致的多个消息交换的临时关联性以及因果关联性;
- 描述了与该模式相一致的消息交换的正常终止以及异常终止。
对于传输绑定规范而言,它可以声明是支持一个或多个指定的传输消息交换模式。而传输消息交换模式则是通过URI来指定的(使用URI命名)。传输消息交换的生命周期是由传输消息交换模式所支配的。
表1中描述了一些特定的属性定义,这些属性是用于支持传输消息交换模式的描述的。当然在特定的传输消息交换模式(TMEP)中,我们还会使用一些其他的属性,不过,在表1罗列出来的属性对于所有的传输消息交换模式都普遍适用。
Table 1.支持传输消息交换模式的属性定义
|
属性名URI
|
属性值描述
| | transport:ExchangePatternName | 一个URI,用于指定在操作中使用的传输消息交换模式。 | | single:Role | 一个URI,用于表示本地SOAP结点的角色,这个角色是模式特定的,是与封装属性的容器所指示的传输消息相关的。 | | single:State | 一个与在single:Role中传输的基值相关的URI,用于表示传输消息交换的当前状态,而该传输消息交换是由封装属性的容器来指明的。该值由绑定实例管理,并且可以被其他监控消息交换流程的实体所检测。 | | transport:FailureReason | 一个URI,用于表示一个模式相关而绑定独立的消息交换错误原因。传输绑定规范可以定义自行定义一些属性以传递更多的绑定相关的错误细节。 | | transport:CurrentMessage | 一个抽象结构,用于表示在一个消息交换过程中的当前消息。这个结构抽象了SOAP Envelope和一些其他的因消息传输操作而随SOAP Envelople传输的结构。根据模式相关的状态,该结构可能分别对应传入或传出的消息。 | | transport:ImmediateDestination | 一个URI,用于表示传出消息的紧接着的目标。 | | transport:ImmediateSender | 一个URI,用于表示传入消息紧靠着的那个发送者。 |
注意:以上的这些属性的名称都是一个URI,同时属性的值也可能是一个URI,URI是一个数据类型,如同字符串。
消息交换模式名称
由URI "http://www.example.org/2001/12/soap/transport-mep/single-request-response/"指定的消息交换模式可简称为"single-request-response","单一请求/响应模式"。
传输绑定规范可以使用这个传输消息交换模式的全名来声明他们对于这个传输消息交换模式及其中定义的相关语义的支持。
表2罗列了一些标准的前缀映射,在下面的描述中,我们假定这些映射已经存在了。
Table 2.标准命名空间前缀映射
|
前缀
|
命名空间
| | transport | http://www.example.org/2001/12/soap/bindingFramework/TransportExchangeContext/ | | mep | http://www.example.org/2001/12/soap/transport-mep/ | | fail | http://www.example.org/2001/12/soap/transport-mep/FailureReasons/ | | single | http://www.example.org/2001/12/soap/transport-mep/single-request-response/ |
单一请求响应简介
"single-request-response"传输消息交换模式定义了一个包含两个消息的交换模式,交换是发生在SOAP消息路径中两个相邻SOAP结点间的。在发出请求的SOAP结点(Requesting SOAP Node)和响应请求的SOAP结点(Responding SOAP Node)之间,来回的两个方向各有一个消息被交换。
与"single-request-response"传输消息交换模式相一致的消息交换的正常操作是这样的:首先一个请求消息从发出请求的SOAP结点被传输到响应请求的SOAP结点,当响应请求的SOAP结点成功处理了请求消息之后,紧接着,响应消息从响应请求的SOAP结点被传输发出请求的SOAP结点。
与"single-request-response"传输消息交换模式相一致的消息交换的异常操作可能因以下一些错误的发生而被实施,这些错误包括:在传输请求消息时发生错误、响应请求的SOAP结点在处理请求消息的时候发生错误,或是传输响应消息时发生错误。这些错误可以不被报告,无论是在请求的过程中,还是在响应的过程中,又或是在消息交换中涉及的两个SOAP结点内部,具体实现都可以选择不报告错误。同时,由于在消息交换中的每个SOAP结点,由于它们对于消息交换的成功完成的判断标准存在着差异,因此异常操作的触发也相应存在着差异。
正式定义
为了初始化一个与"single-request-response"传输消息交换模式相一致的传输消息交换,发出请求的SOAP结点需要首先初始化一个本地的传输消息交换的上下文(context)。这个上下文按照如下表3所示被初始化。
Table 3.发出请求的SOAP结点所初始化的本地的传输消息交换的上下文
|
属性名URI
|
属性值描述
| | transport:ExchangePatternName | http://www.example.org/2001/12/soap/transport-mep/single-request-response/ | | single:Role | RequestingSOAPNode | | single:State | Requesting | | transport:FailureReason | (无) | | transport:CurrentMessage | 请求消息的一个摘要 | | transport:ImmediateDestination | 一个表示响应请求的SOAP结点的URI标识 |
另外,如果我们在"single-request-response"传输消息交换模式上同时应用了一些特性的话,那么与特定传输消息交换实例相关的特性操作中使用的另一些属性,也应该在此时根据相应的特性规范来进行初始化。
一旦初始化完成后,这个传输消息交换上下文的控制权就被传递给本地绑定实例(当然这个绑定实例需要和传输消息交换模式相一致)。
下面的图1显示了,在整个消息交换的生命周期中,在发出请求的SOAP结点和相应请求的SOAP结点中的逻辑状态转移。当每个SOAP结点的single:State属性值发生了更新时,更新的值即时反映了由本地绑定实例所认定的消息交换的当前状态。这些状态名是一些相对URI(Relative URI),他们都是基于一个基URI(Base UDI)的,这个基URI就是在本地传输消息交换上下文中single:Role属性所包含的值。
Figure 1.发出请求的SOAP结点和响应请求的SOAP结点中的逻辑状态转移
当响应请求的SOAP结点开始接收传入的请求消息时,本地的绑定实例将会在响应请求的SOAP结点内初始化(逻辑上)一个传输消息交换上下文。这个上下文按照如下表4所示被初始化。
Table 4.响应请求的SOAP结点所初始化的本地的传输消息交换的上下文
|
属性名URI
|
属性值描述
| | transport:ExchangePatternName | http://www.example.org/2001/12/soap/transport-mep/single-request-response/ (这个属性值在整个消息交换的生命周期一开始就已经被初始化) | | single:Role | RespondiingSOAPNode | | single:State | Receiving | | transport:FailureReason | (无) | | transport:CurrentMessage | NULL | | transport:ImmediateSender | 一个表示发出请求的SOAP结点的URI标识 |
下面我们使用图表的形式来定义SOAP结点的状态转移时的操作:
Table 5.发出请求的SOAP结点状态转移时的操作定义
|
当前状态
|
下一状态
|
操作
| | Requesting | Fail | 将属性transport:FailureReason的值设置成"transmissionFailure" | | Waiting | | | Waiting | Fail | 将属性transport:FailureReason的值设置成"NoResponse" | | Receiving | | | Receiving | Fail | 将属性transport:FailureReason的值设置成"ReceptionFailure" | | Success | 将属性transport:ImmediateSender的值设置成:表示响应消息(Respond Message)发送者的URI(该值是有可能与transport:ImmediateDestination属性的值不相同的);将transport:CurrentMessage属性的值替换成响应消息的摘要。 |
Table 6.响应请求的SOAP结点状态转移时的操作定义
|
当前状态
|
下一状态
|
操作
| | Receiving | Fail | 将属性transport:FailureReason的值设置成"ReceptionFailure" | | Processing | 将属性transport:ImmediateSender的值设置成:表示请求消息(Request Message)发送者的URI;将transport:CurrentMessage属性的值替换成请求消息的摘要;将传输消息交换上下文的控制权转交给SOAP处理器 | | Processing | Fail | 将属性transport:FailureReason的值设置成"NoResponse" | | Responding | SOAP处理器已经将transport:CurrentMessage属性的值替换成响应消息的摘要 | | Responding | Fail | 将属性transport:FailureReason的值设置成"transmissionFailure" | | Success | |
错误处理
在"single-request-response"传输消息交换模式的操作处理中,参与的SOAP结点可以产生SOAP Fault。
如果在处理请求消息的过程中产生了SOAP Fault,那么,这则消息面向最终的响应请求SOAP结点的转发应当被中止,同时产生的SOAP Fault应当被转发给最初的发出请求SOAP结点,形式上,代替了原先需要发送的响应消息。
如果在处理响应消息的过程中产生了SOAP Fault,那么,同时产生的SOAP Fault同样应当被转发给最初的发出请求SOAP结点,形式上,代替了原先需要发送的响应消息。
经由SOAP中介的操作
"single-request-response"传输消息交换模式可以被扩展而支持SOAP消息路径。扩展的"single-request-response"传输消息交换模式能够在多个传输绑定结点上建立一个扩展"single-request-response"传输消息交换,通过扩展了多个SOAP中间介结点以实现SOAP消息路径的支持。
默认情况下,响应消息的传输与请求消息的传输所经过的SOAP结点集是相同的,差别仅仅在于两者所经过的SOAP结点的次序恰恰相反。一些特别的SOAP扩展可以更改这个默认的行为,例如SOAP路由扩展就需要更改这一默认行为,以支持动态选择SOAP路径。
当SOAP中间介结点接收到请求消息后,可以处理该消息,并将其朝着最终响应请求SOAP结点转发。默认情况下,只有当SOAP中间介接收到响应消息之后,响应消息才能被朝着最初发出请求SOAP结点转发,也就是说,最终响应请求SOAP结点不能将响应消息直接发往最初发出请求SOAP结点。
当SOAP中间介在转发请求消息或者接收响应消息时发生错误,SOAP中间介结点同样可以产生SOAP Fault。
参考资料
关于作者  | 
|  |
柴晓路: 上海得易电子商务技术有限公司(
DealEasy)首席系统架构师、XML Web Sevices技术顾问,
WS-I Working Group成员,
UDDI Advisory Group成员,
UDDI-China.org创始人,IBM developerWorks专栏作家。2000年获复旦大学计算机科学硕士学位,曾在国际计算机科学学术会议(ICSC)、亚太区XML技术研讨会(XML Asia/Pacific'99)、中国XML技术研讨会(北京)、计算机科学期刊等各类国际、国内重要会议与期刊上发表论文多篇。专长于Web Services技术架构、基于XML的系统集成和数据交换应用及方法,同时对数据库、面向对象技术及CSCW等技术比较擅长。
|
对本文的评价
|