2008年1月3日星期四

WebService_005:实验说明4种SOAP binding的区别

开发工具:Oracle JDeveloper Studio 10.1.3.3.0。
运行环境:Oracle SOA Suite 10.1.3.1.0 + Oracle Database 10g Express Edition。
实验目的:彻底搞清楚4种SOAP binding的不同之处。

首先从style上划分,SOAP binding 分为两种:document-style和RPC-style,二者最直观的区别是:
◆ document-style
(1)WSDL中message的定义,其中的part是用XML schema的element定义的,比如:
<message name="LoanFlowRequestMessage">
<part name="payload" element="s1:loanApplication"/>
</message>
(2)SOAP消息中Body部分直接包含消息内容(一个XML文档)。服务器负责将XML文档映射成内存对象(参数、方法调用等等)。
◆ RPC-style,
(1)WSDL中message的定义,其中的part是用XML schema的type定义的,比如:
<message name="LoanFlowRequestMessage">
<part name="payload" type="s1:LoanApplicationType"/"/>
</message>
(2)SOAP消息中Body部分包含的XML节点是该服务的调用方法名,然后依次包含方法调用的各个参数。

其次从use上划分,分为encoded和literal。
◆ encoded
表示XML的消息使用类型属性引用抽象数据类型,使用Section 5编码(SOAP1.1规范第五章定义的编码)进行XML的序列化和反序列化。
◆ literal
表示XML的消息使用type属性或者element元素引用具体的XML Schema定义,也就是说,根据XML Schema进行XML的序列化和反序列化。

style和use一组合,就形成了4种不同的SOAP binding。
对于document-style,又分为两种:document-literal bared 和 document-literal wrapped。
• document-literal bared (简称document-literal),其服务调用方法只能有一个参数。
从类HelloDBImpl 生成 HelloDBWebService.wsdl
package com.javaneverdie;
public class HelloDBImpl {
public String hello(String str) {
return "Hello, document-literal bared, " + str;
}
}
<types>
<schema ...>
<element name="helloElement" type="string" nillable="true"/>
<element name="helloResponseElement" type="string" nillable="true"/>
</schema>
</types>

SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://javaneverdie.com/types/"> <ns1:helloElement>Ping Ma</ns1:helloElement>
</soap:Body>
</soap:Envelope>


SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body> <ans1:helloResponseElement xmlns:ans1="http://javaneverdie.com/types/">Hello, document-literal bared, Ping Ma</ans1:helloResponseElement>
</env:Body>
</env:Envelope>

document-literal wrapped(简称document-wrapped ),其服务调用方法的参数可以多个,所谓wrapped是指它的参数全部被“wrapped”一个复杂的数据类型(complexType)中。
从类HelloDW1Impl 生成 HelloDW1WebService.wsdl
package com.javaneverdie;
public class HelloDW1Impl {
public String hello(String str) {
return "Hello, document-literal wrapped, " + str;
}
}
<types>
<schema ...>
<element name="helloElement">
<complexType>
<sequence>
<element name="str" type="string" nillable="true"/>
</sequence>
</complexType>
</element>
<element name="helloResponseElement">
<complexType>
<sequence>
<element name="result" type="string" nillable="true"/>
</sequence>
</complexType>
</element>
</schema>
</types>

SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://javaneverdie.com/types/">
<ns1:helloElement>
<ns1:str>Ping Ma</ns1:str>
</ns1:helloElement>
</soap:Body>
</soap:Envelope>
注意:SOAP消息中helloElement来自于输入信息的element。


SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/types/">
<env:Body>
<ns0:helloResponseElement>
<ns0:result>Hello, document-literal wrapped, Ping Ma</ns0:result>
</ns0:helloResponseElement>
</env:Body>
</env:Envelope>

对于RPC-style,也分为两种:RPC-literal 和 RPC-encoded。
• RPC-literal
package com.javaneverdie;
public class HelloRLImpl {
public String hello(String str1, String str2) {
return "Hello, RPC-literal, " + str1 + ", " + str2;
}
}
SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://javaneverdie.com/">
<soap:Body>
<ns:hello>
<str1>Ping</str1>
<str2>Ma</str2>
</ns:hello>
</soap:Body>
</soap:Envelope>
注意:SOAP消息中hello来自于服务调用的方法名。

SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/">
<env:Body>
<ns0:helloResponse>
<result>Hello, RPC-literal, Ping, Ma</result>
</ns0:helloResponse>
</env:Body>
</env:Envelope>

• RPC-encoded
package com.javaneverdie;
public class HelloREImpl {
public String hello(String str1, String str2) {
return "Hello, RPC-encoded, " + str1 + ", " + str2;
}
}
SOAP 请求消息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://javaneverdie.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<ns:hello>
<str1 xsi:type="xsd:string"></str1>
<str2 xsi:type="xsd:string"></str2>
</ns:hello>
</soap:Body>
</soap:Envelope>

SOAP 响应消息如下:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns0="http://javaneverdie.com/">
<env:Body>
<ns0:helloResponse env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<result xsi:type="xsd:string">Hello, RPC-encoded, Ping, Ma</result>
</ns0:helloResponse>
</env:Body>
</env:Envelope>

参考文献
1. 《我应该采用哪一种 WSDL 样式?》 作者:
http://www.ibm.com/developerworks/cn/webservices/ws-whichwsdl/
2. 《SOAP中 RPC/ENC 为什么被抛弃?》作者: http://www.javaeye.com/topic/145061

没有评论: