WS-Addressing规范主要描述了两个概念:EndpointReference 以及Message Addressing Properties。
在详细介绍EndpointReference前,首先了解一下Endpoint的概念。在Web Services中代表一类逻辑功能的服务实现可能存在不同的Endpoint,每一个Endpoint可能代表了一种不同的绑定方式,甚至对外表现出不 同的接口,比如Endpoint A可能使用TCP协议通讯,而Endpoint B则可能使用Http协议。通过EndpointReferrence我们就可以引用到相应的Endpoint上,从而访问该服务。因此你可以想象 EndpointReferrence的功能和WSDL中的Service元素很相象,下面就是EndpointReferrence的XML Infoset。
<wsa:EndpointReference> <wsa:Address>xs:anyURI</wsa:Address> <wsa:ReferenceProperties>... </wsa:ReferenceProperties> ? <wsa:ReferenceParameters>... </wsa:ReferenceParameters> ? <wsa:PortType>xs:QName</wsa:PortType> ? <wsa:ServiceName PortName="xs:NCName"?>xs:QName</wsa:ServiceName> ? <wsa:Policies> ... </wsa:Policies>? <xs:any/>* </wsa:EndpointReference>
其中由< wsa:Address > 和< wsa:ReferenceProperties > 元素共同决定了服务地址。
而以下是WSDL的Service元素
<service name="StockTraderService"> <port name="StockTraderServiceSoap" binding="tns:StockTraderServiceSoap"> <soap:address location="http://idior.cnblogs.com/StockTrader.asmx" /> </port> </service>
不过在WSDL中并没有考虑到当一个有状态的服务(尽管大多数的服务应该没有状态)拥有多个实例时的情况,此时如何定位到某个特定的服务实例?比如 当用户向Service发出请求后,服务器为该用户创建了一个实例,其中维持了用户对服务请求的状态,典型的例子如购物篮。为了让该用户在下次请求服务时 依旧能定位到上次的服务实例,此时Service将在第一次的请求的回复消息中携带上该服务实例的EndpointReference,而不仅仅是一个 URL地址,如此用户在下次访问服务时就可以利用< wsa:ReferenceProperties > 元素来定位到之前的那个服务实例,从而维持住用户的状态。如下图所示:
Figure 1: A SOAP message containing a reference to the instance of the service that sent it.
虽然在WSRF(Web Services Resource Framework)和WS-Notification规范中都使用了EndpointReference的这个特性来定位Service, 但是该方法仍然值得商榷。通过额外的属性而不是仅仅依靠URI来定位资源,这点是否合适?在W3C的Architecture of the World Wide Web, Volume One一文中认为"Distinct Resources must be assigned to Distinct URIs",并且在Roy Thomas Fielding提出的REST的架构中也充分证明了这一点。 如果你查看一下Web Services Addressing Working Issues List会发现其中的第一个Issues就是讨论的这个问题,并且事实证明Web Services Addressing Working Group抛弃了使用< wsa:Address > 和< wsa:ReferenceProperties > 元素联合定位服务的方法。在新的版本的WS-Addressing规范中EndpointReference的XML Infoset已经被修改成下面这个样子:
<wsa:EndpointReference> <wsa:Address>xs:anyURI</wsa:Address> <wsa:ReferenceParameters>xs:any*</wsa:ReferenceParameters> ? <wsa:Metadata>xs:any*</wsa:Metadata>? </wsa:EndpointReference>
虽然在新方案中仍旧保留了< wsa:ReferenceParameters > 元素,但是该元素并不像之前的< wsa:ReferenceProperties > 对 服务定位起决定作用,它仅仅是一个附带属性,你可以利用它来定位,但Web Services Addressing Working Group小组并不推荐这些做法。这么一来就不知道WSRF(Web Services Resource Framework)和WS-Notification规范的工作组如何应对了,估计也只能用< wsa:ReferenceParameters > 来替代了。
EndpointReference 新的设计方案使得EndpointReference和URI十分接近,而相关的文章又非常之少,并且对于在服务请求前通过何种方式获得 EndpointReference我也一直持有疑惑,因此EndpointReference的介绍就不再深入展开。
My Doubt 个 人理解Client可以从第一次请求Service后从Service的返回消息中Message Addressing Properties的ReplyTo元素获得Service EndpointReference,而如何在第一次请求服务前获得EndpointReference就不得而知了
相关文章:
WS-Addressing Message Addressing Properties (转)