`

WS-Addressing Message Addressing Properties (转)

阅读更多

相对EndpointReference而言,个人认为在WS-Addressing规范中Message Addressing Properties的作用显的更加重要,下面将对它做详细介绍。与EndpointReference用于描述服务的地址不同,Message Addressing Properties作为SOAP Head的扩展将包含在每一个SOAP 消息中,用于该消息的寻址。首先来看一下它的XML Infoset:

 

< wsa:To > xs:anyURI</ wsa:To > 
< wsa:From > wsa:EndpointReferenceType</ wsa:From > 
< wsa:ReplyTo > wsa:EndpointReferenceType</ wsa:ReplyTo > 
< wsa:FaultTo > wsa:EndpointReferenceType</ wsa:FaultTo > 
< wsa:Action > xs:anyURI</ wsa:Action >
< wsa:MessageID > xs:anyURI</ wsa:MessageID > 
< wsa:RelatesTo RelationshipType ="xs:anyURI" ?> xs:anyURI</ wsa:RelatesTo > 
< wsa:ReferenceParameters > xs:any*</ wsa:ReferenceParameters > 
 

 

下面这张图更加清楚的表示出Message Addressing Properties与SOAP 消息的关系。

                         

其中< wsa:MessageID > 用于标识一个消息,而< wsa:RelatesTo> 表示该消息与另一消息关系,元素值是另一消息的MessageID。< wsa:RelatesTo>元 素对实现异步消息交换有很重要的作用,这点在后面的文章中会具体介绍。
我 把剩下的Message Addressing Properties分成了两类属性,一类(Go)指出该消息的去向,另一类(Back)为该消息可能存在的返回消息提供寻址功能。也就是说Go类型的属 性才与该消息的寻址直接相关,而Back类型的属性对消息自身的寻址没有任何影响,纯粹是为了与该消息对应的返回消息寻址所用。显而易见,如果该消息不存 在返回消息,那么Back类型的属性就不需要了。下面具体介绍每一类属性。

Go类型的属性用于消息自身的寻址,自然也是最重要的,在了解了EndpointReference的概念后,对于其中的< wsa:To >< wsa:ReferenceParameters > 属性也就很容易理解了。把消息所请求的Service的EndpointReference的值搬过来就行了,如下图所示:




而另一个属性< wsa:Action > 则显得比较陌生,还记得通过Http协议访问Web Services时Http Head中的SOAPAction元素吗?

POST /TravelAgentServices/Hotel.asmx HTTP/1.1

Host: localhost

Content-Type: text/xml; charset=utf-8

Content-Length: length

SOAPAction: "http://idior.cnblogs.com/hotel/PlaceOrder"

 
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope>
  ...
</soap:Envelope>
 


< wsa:Action > 此时的作用与SOAPAction相当,现在的问题就在于这个Action的值从何而来?要想知道答案,首先需要了解< wsa:Action > 的 作用。假设你在SOAP消息中包含了一个订单,当这个消息达到Service之后,你希望它怎么处理这个订单呢?是为你新增这个订单,还是将这个订单删 除,还是更新?同一个消息,Service可能提供了多种处理方法,你希望Service对你所发送的消息如何处理?在消息中指定处理该消息的语义,这就 是< wsa:Action > 所起的作用。说白了,就是通过< wsa:Action > 指定消息到达Service时,究竟触发服务中的哪个方法完成对消息的处理。
知道了< wsa:Action > 用于指定将处理该消息的方法,那么不难想象它的值来自于WSDL。
它的构成如下:

[target namespace][delimiter][port type name][delimiter][input|output name]
 

 

看了下面的例子就很容易明白了:

< definitions targetNamespace ="http://idior.cnblogs.com/resSvr" >
  ...
  < portType name ="reservationInterface" >
     < operation name ="opCheckAvailability" >
       < input message ="tns:checkAvailability" name ="CheckAvailability" />
       < output message ="tns:checkAvailabilityResponse" name ="Availability" />
     </ operation >
  </ portType >
  ...
</ definitions >    

[targetNamespace] = http://idior.cnblogs.com/resSvr
[port type name] = reservationInterface
[input name] = CheckAvailability
[output name] = CheckAvailabilityResponse
Applying the pattern above with these values we have:
input action = http://idior.cnblogs.com/resSvr/reservationInterface/CheckAvailability
output action = http://idior.cnblogs.com/resSvr/reservationInterface/CheckAvailabilityResponse
 




当然一种更简单明了的方法就是在WSDL中直接指定某个方法的输入输出消息的Action,如下所示:

< definitions targetNamespace ="http://idior.cnblogs.com/resSvc" ...>
  ...
  < portType name ="reservationInterface" >
    < operation name ="opCheckAvailability" >
      < input message ="tns:checkAvailability"
        wsa:Action ="http://idior.cnblogs.com/resSvc/CheckAvailability" />
      < output message ="tns:checkAvailabilityResponse"
        wsa:Action ="http://idior.cnblogs.com/resSvc/CheckAvailabilityResponse" />
    </ operation >
  </ portType >
  ...
</ definitions >
 


综合得到Message Addressing Properties中Go类型的属性设定,如下图所示:



从以上介绍的Message Addressing Properties中的属性可以看出,WS-Addressing规范就是把原来处于传输层的寻址信息提升到更高层的消息层面,直接在SOAP消息中包含这些信息,这样就可以摆脱对特定传
输协议的约束,从而使得SOAP消息的传输与具体传输协议无关,这也是Loosely Coupled的体现之一。

      Tip 把底层传输 协议的功能提到消息层面再次加以实现,这种方法在WS-*规范中广为采用,比如在以往的中间件系统中并非没有对安全,可靠性以及事务的支持,只不过这种支 持依赖于某一特定的实现,这样就失去了通用性,也就无法成为良好的集成方案,当把这些功能放在SOAP消息层面加以实现就可以摆脱这种对底层实现的依赖, 而获得更优秀的互操作性。此时,为了避免各持一言,所以才由标准化组织来统一各种功能在消息层面的所作的扩展格式,WS-*也就是在这种情况下出现的。

 

Request- Response Pattern in WS-Addressing

Request-Response 消息交换模式(Message Exchange Pattern)是最经典也是最常用的MEP。在Request-Reply MEP中涉及两个消息-Request Message与Response Message。通常我们使用Http协议访问某个Web Service时,就是采用的这个消息交互模式。不过除了使用Http协议的同步式Request-Response MEP,还有借助诸如TCP,SMTP,MSMQ协议的异步式Request-Response MEP。下面就将分别对Request Message与Response Message中Message Addressing Properties在同步式和异步式下的内容做详细介绍。

 

Request Message
在之前对Message Addressing Properties中Go类型的属性的介绍中,并没有涉及所采用的MEP,其实上述的介绍仍适用于Request-Response MEP,因此不论在Request Message还是Response Message中有关Go类型属性的设定方法都如前所述,只不过它们各自所依据的EndpointReference不同罢了。因此现在重点需要了解在 Request Message中Back类型的属性如何设定。Back类型的属性的值都是EndpointReference类型,其中< wsa:From > 则表示发送该Request Message的地址,< wsa:ReplyTo > 指定了该Request Message的Response Message将发向的地址,这个值可能与< wsa:From > 相同也可能不同。FaultTo则指出当消息处理出现错误时错误消息将去往的地址。在这其中< wsa:ReplyTo > 属性是必须的。其实在Http这种同步式Request- Response的MEP中,因为请求和回应都是使用的同一信道,所以并不需要< wsa:ReplyTo > 属性,不过为了形式上的统一,WS-Addressing规范还是强制了在Request- Response的MEP下< wsa:ReplyTo > 属性不能为空。这样也方便Service辨识Client的MEP,如果ReplyTo有值则是Request-Response,如果没有则是OneWay。对于同步式的Request-Response MEP,你可以采用"http://www.w3.org/2005/08/addressing/anonymous "来设定< wsa:ReplyTo > 的值, 如果你另外设定一个EndpointReference, 那么Service会关闭当前的Http连接,利用刚设定的EndpointReference新建一个连接用于发送Response Message。

为了使得在异步情况下,Response Message能够通过< wsa:RelatesTo> 属性与Request Message关联上,Request Message中< wsa:MessageID > 属性也是必须的。     

       Note 以上都是最新的规范中的内容,在WSE3.0中并没有完全体现,如使用Http协议的Request-Response MEP中ReplyTo属性为空。

下图显示了如何构造Request Message的Message Addressing Properties:




Response Message
Response Message中Go类型的属性的设定来源于Request Message中的< wsa:ReplyTo > 属性,< wsa:ReplyTo > 的类型也是EndpointReference,因此除了EndpointReference的指向不同,Response Message中Go类型属性的设定与Request Message基本一致,不过需要注意此时的< wsa:Action > 属性是采用的WSDL中Output参数的< wsa:Action > 值。 在采用异步式的Request-Response MEP时,由于Client发出Request Message的和接受Response Message的动作并不处于同一个线程,为了让Client在接受到的Response Message后能够将其与Request Message关联上,此时将使< wsa:RelatesTo > 指向Request Message中的< wsa:MessageID >

下图显示了如何构造Response Message的Message Addressing Properties:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics