2010-4-6 蒋彪 于南京
为什么会需要WS-Addressing?在出现WS-Addressing之前,我们都是如何让服务之间互相得到数据的呢?
当然,我们是通过http数据包来定义的,一段http数据包里包括了数据包发送的目的地,发送过去的动作,发送的格式等等,这个数据包直接通过复杂的网络,发送过去,让接受方接受。(具体请参照下图中的红色加粗字体)
---[HTTP request - http://localhost:80/jaxws-wsaddressing_replyto/addnumbers]--- Content-length: 627 Content-type: text/xml;charset=utf-8 Accept: text/xml, multipart/related Soapaction: "http://server.wsaddressing_replyto/AddNumbersImpl/addNumbersRequest" <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S=http://schemas.xmlsoap.org/soap/envelope/ xmlns:wsa="http://www.w3.org/2005/08/addressing"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing"> http://localhost:80/jaxws-wsaddressing_replyto/addnumbers</To> <Action xmlns="http://www.w3.org/2005/08/addressing"> http://server.wsaddressing_replyto/AddNumbersImpl/addNumbersRequest </Action> </S:Header> <S:Body> <ns2:addNumbers xmlns:ns2="http://server.wsaddressing_replyto/"> <arg0>10</arg0> <arg1>20</arg1> </ns2:addNumbers> </S:Body> </S:Envelope> -------------------- |
但是,这种处理方法,对应简单的点到点数据传输是可以的,但是一旦遇到了异步的,分布式的系统的话,这样的解决方法就不行了,具体问题如下:
・ 如果在异步传输下,服务A发送数据给服务B,但是服务B的正常响应,非正常响应,错误响应都是不同的,那么怎么在http数据包来定义呢?
・ 如果服务A发送数据给服务B,但是调用的是服务B的不同版本。比如服务B有三个不同的版本,需要通过调用时候传递的参数来决定调用的版本。那么简单的http数据包定义能应付吗?
为了解决这些技术问题,IBM,MS,BEA等公司联合推出了WS- Addressing协议。
WS- Addressing协议的最新官方文档如下:
http://www.w3.org/Submission/ws-addressing/ |
WS- Addressing协议最简单的定义就是,在SOAP消息的Header中,用一系列XML标签定义了服务传递中间的目的地,Action,ReplyTo,Fault处理等等传输层细节。
(具体请参照下图中的红色加粗字体)
---[HTTP request - http://localhost:80/jaxws-wsaddressing_replyto/addnumbers]--- Content-length: 627 Content-type: text/xml;charset=utf-8 Accept: text/xml, multipart/related Soapaction: "http://server.wsaddressing_replyto/AddNumbersImpl/addNumbersRequest" <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S=http://schemas.xmlsoap.org/soap/envelope/ xmlns:wsa="http://www.w3.org/2005/08/addressing"> <S:Header> <wsa:To>http://localhost:80/jaxws-wsaddressing_replyto/addnumbers </wsa:To> <wsa:ReplyTo> <Address>http://www.w3.org/2005/08/addressing/anonymous </Address> </wsa:ReplyTo> <wsa:FaultTo> <Address>http://www.w3.org/2005/08/addressing/anonymous </Address> </wsa:FaultTo> <wsa:MessageID>uuid:71dc765e-1c1f-4fff-ac77-1681eb416005 </wsa:MessageID> <To xmlns="http://www.w3.org/2005/08/addressing"> http://localhost:80/jaxws-wsaddressing_replyto/addnumbers</To> <Action xmlns="http://www.w3.org/2005/08/addressing"> http://server.wsaddressing_replyto/AddNumbersImpl/addNumbersRequest </Action> </S:Header> <S:Body> <ns2:addNumbers xmlns:ns2="http://server.wsaddressing_replyto/"> <arg0>10</arg0> <arg1>20</arg1> </ns2:addNumbers> </S:Body> </S:Envelope>-------------------- |
我们在上面谈了,为什么需要WS-Addressing协议。下面我们来谈一谈WS-Addressing是如何传输数据的。
WS-Addressing协议通过在SOAP消息的header中加入数据的方式来传送数据。具体的传送方法有如下两种:
・ Endpoint Reference
・ Message Addressing Properties
我们可以打个最简单的比方来解释上面两种技术,如果南京的小李要寄信给上海的小王,那么Message Addressing Properties就好像信封的格式(比如什么地方写邮编,什么地方写地址),而Endpoint Reference就好像信封上面具体的邮编,地址的内容。
(具体如下所示,红色加粗的是Message Addressing Properties,蓝色加粗的是Endpoint Reference)
s:Envelope xmlns:s="..." xmlns:wsa="..."> <s:Header> <wsa:Action>http://skonnard.com/SubmitClaim</wsa:Action> <wsa:To>http://skonnard.com/Claims/Submit.asmx</wsa:To> <wsa:From> <wsa:Address>http://skonnard.com/main/sub.asmx</wsa:Address> <wsa:ReferenceProperties> <c:PatientProfile>123456</c:PatientProfile> <c:CarrierID>987654</c:CarrierID> </wsa:ReferenceProperties> </wsa:From> <wsa:ReplyTo> <wsa:Address>http://skonnard.com/resp/resp.asmx</wsa:Address> <wsa:ReferenceProperties> <c:PatientProfile>123456</c:PatientProfile> <c:CarrierID>987654</c:CarrierID> </wsa:ReferenceProperties> </wsa:ReplyTo> <wsa:FaultTo> <wsa:Address>http://skonnard.com/fault/err.asmx</wsa:Address> <wsa:ReferenceProperties> <c:PatientProfile>123456</c:PatientProfile> <c:CarrierID>987654</c:CarrierID> </wsa:ReferenceProperties> </wsa:FaultTo> </s:Header> <s:Body xmlns:c="http://example.org/claims"> <c:SubmitClaim> ... </c:SubmitClaim> </s:Body> </s:Envelope> |
最后我们来谈一谈WS-Addressing到底能传输什么数据的?
数据分类 |
标签名 |
标签含义 |
Endpoint Reference |
/wsa:EndpointReference |
|
/wsa:EndpointReference/wsa:Address |
|
|
/wsa:EndpointReference/wsa:ReferenceProperties/ |
|
|
/wsa:EndpointReference/wsa:ReferenceProperties/{any} |
|
|
/wsa:EndpointReference/wsa:ReferenceParameters/ |
|
|
/wsa:EndpointReference/wsa:ReferenceParameters/{any} |
|
|
/wsa:EndpointReference/wsa:PortType |
|
|
/wsa:EndpointReference/wsa:ServiceName |
|
|
/wsa:EndpointReference/wsa:ServiceName/@PortName |
|
|
/wsa:EndpointReference/wsp:Policy |
|
|
/wsa:EndpointReference/{any} |
|
|
/wsa:EndpointReference/@{any} |
|
|
Message Addressing Properties |
/wsa:MessageID |
为了防止冗余数据传输的标志 |
/wsa:RelatesTo |
关联URI |
|
/wsa:ReplyTo |
正常响应的URI |
|
/wsa:From |
发出请求的URI |
|
/wsa:FaultTo |
出错响应的URI |
|
/wsa:To |
发送目的地的URI |
|
/wsa:Action |
接受信息方处理的URI |
以上