当前位置: 代码迷 >> Web前端 >> Web Services:从洽,编码,交换模型
  详细解决方案

Web Services:从洽,编码,交换模型

热度:215   发布时间:2012-11-13 10:00:51.0
Web Services:自洽,编码,交换模型
1, 自洽
以前曾经写过:
目前WebService不是自洽的,即一个WebService方法的参数和返回值不能是另外一个WebService,因此你不能在WebService的返回值上调用业务逻辑方法;顶多开发包做点手脚,包装几个getter/setter方法,或同构平台上在客户端拥有服务端的类定义,可以调用其方法,像.Net平台上的DataSet;参考开发包的处理,我们可以自己为WebService的返回值加入业务逻辑方法
a,开发包无非是为客户端生成一堆代理类,完成序列化/反序列化,解析远程调用协议等
b,我们可以修改这些代理类,加入业务逻辑方法,只要不影响序列化/反序列化,解析远程调用协议那些原有的部分就行
参考以前的远程过程调用协议,COM,RMI等,都能通过一个远程对象返回另外一个远程对象,可以调用各种方法,WebService完全应该定义其返回值、参数可以是另外一个WebService 
最近看了<<我应该采用哪一种WSDL样式>>, 文中提到RPC/Literal编码方式的href属性,让我联想起以前的想法,其实如果规定客户端Stub必须是可序列化的,那么是否就有可能解决WebService的参数和返回值可以是另外的WebService呢(或说是另外的WebService的客户端Stub类呢)?
2. Content-Type
SOAP 1.1 HTTP/SOAP 消息的媒体类型为“text/xml”,其编码处理是在 RFC2376 中定义的。而 SOAP 1.2 HTTP/SOAP 消息的媒体类型为“application/soap+xml”,其编码处理是在 RFC3023 中定义的。这些 RFC 规范定义了下列行为:

SOAP 1.1: HTTP/SOAP 请求的字符集由 HTTP 头中的 ContentType 字符集参数确定。在 SOAP 消息的 XML 声明部分定义的编码特性将被忽略。如果不指定 ContentType 字符集参数,字符集将被视为 US-ASCII。

SOAP 1.2: HTTP/SOAP 请求的字符集由 HTTP 头中的 ContentType 字符集参数确定。在 SOAP 消息的 XML 声明部分定义的编码特性将被忽略。如果未指定 ContentType 的字符集参数,将使用在 XML 声明部分定义的编码特性。如果 ContentType 字符集参数或 XML 声明的编码特性均未定义,它将被视为 UTF-8。
Content-Type: text/html;charset=GB2312
Content-Type: text/xml; charset=utf-8
3,UTF-8,Axis?支持其它编码?How to ?希望各位看官给个下面问题的答案
POST /wstest/NetWebService/SampleSer<wbr></wbr>vice HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8  <!--1, how can I change it to charset=shift_jis using axis? Thanks-->
Content-Length: length
SOAPAction: "http://tempuri.org/max"

<?xml version="1.0" encoding="utf-8"?> <!--2, how can I change it to encoding="shift_jis" using axis? Thanks-->
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchem<wbr></wbr>a-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchem<wbr></wbr>a
" xmlns:soap="http://schemas.xmlsoap.org<wbr></wbr>/soap/envelope/">
  <soap:Body>
    <max xmlns="http://tempuri.org/">
      <a>int</a>
      <b>int</b>
    </max>
  </soap:Body>
</soap:Envelope>
Assume the operation name is not "max", but a japanese string, and I prefer shift_jis to utf-8, then what should I do?
4, 文档交换vs. RPC模型
以下内容来自<<Webservice 的设计和模式>>
RPC(Remote Procedure Call)本质上就是远程方法的调用。尽管Webservice是基于XML的但是你仍然可以使用远程方法调用这种模式来进行Webservice的实现,尤其是在那种简单的请求相应的模型中。在这个过程中,传输中的XML文件所描述的更多是有关远程方法的信息,比如方法名,方法参数等等。
而文档交换方式,与RPC相比较在XML文件中不是做远程方法的映射,而是一份完整的自包含的业务文档,当Service端收到这份文档后,先进行预处理(比如词汇的翻译和映射),然后再构造出返回消息。这个构造返回消息的过程中,往往不再是简简单单的一个方法调用,而是多个对象协同完成一个事务的处理,再将结果返回。
这两种方式的区别,类似与打电话和发邮件的不同处理方法。在目前,对于第一种方法提供了很多自动化的工具使得远程方法的调用能够很容易的完成,而后一种方法缺少一系列工具的支持,需要开发者手工完成。
尽管如此,在此还是推荐使用文档交换的方式。由于它在以下方面具有RPC所不具备的优点。
  • 使用文档方式,你可以充分利用XML文件的功能去描述和验证一份业务文档,而在RPC模型中XML仅仅被用于描述方法的信息。
  • 使用文档方式,在客户的Service的提供者之间不再需要紧密的约定,而RPC模型需要客户和Service的提供者紧密相连,一旦方法发生变化,客户端就需要做相应的改动。这不符合低耦合系统的要求,而在文档交换方式中则灵活的多。
  • 由于业务数据是自包含的,显然文档模型更利于采用异步处理。

以下内容来自<<我应该采用哪一种WSDL样式>>
Java 方法 : public void myMethod(int x);
Binding Type
WSDL Sample
SOAP Sample
Advantage
Disadvantage
RPC/Encoded
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

<binding .../>
<!-- I won't bother with the details, just assume it's RPC/encoded. -->
<soap:envelope>
<soap:body>
<myMethod>
<x xsi:type="xsd:int">5</x>
</myMethod>
</soap:body>
</soap:envelope>
WSDL 基本达到了尽可能地简单易懂的要求。
操作名出现在消息中,这样接收者就可以很轻松地把消息发送到方法的实现。
  • 类型编码信息(比如 xsi:type="xsd:int" )通常就是降低吞吐量性能的开销。
  • 您不能简单地检验此消息的有效性,因为只有 <x xsi:type="xsd:int">5</x> 行包含在 Schema 中定义的内容;其余的 soap:body 内容都来自 WSDL 定义
RPC/Literal
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

<binding .../>
<!-- I won't bother with the details, just assume it's RPC/
literal. -->
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
</myMethod>
</soap:body>
</soap:envelope>
WSDL 还是基本达到了尽可能地简单易懂的要求。
操作名仍然出现在消息中。
去掉了类型编码
您仍然不能简单地检验此消息的有效性,因为只有 <x xsi:type="xsd:int">5</x> 行包含在 Schema 中定义的内容;其余的 soap:body 内容都来自 WSDL 定义
Document/Litaral
<types>
<schema>
<element name="xElement" type="xsd:int"/>
</schema>
</types>


<message name="myMethodRequest">
<part name="x"
element="xElement"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

<binding .../>
<!-- I won't bother with the details, just assume it's
document/literal. -->
<soap:envelope>
<soap:body>
<xElement>5</xElement>
</soap:body>
</soap:envelope>
没有编码信息
您可以在最后用任何 XML 检验器检验此消息的有效性。 soap:body<xElement>5</xElement> )中每项内容都定义在 Schema 中
WSDL 变得有些复杂。不过,这是一个非常小的缺点,因为 WSDL 并没有打算由人来读取。
SOAP 消息中缺少操作名。而如果没有操作名,发送就可能比较困难,并且有时变得不可能。
Document/Literal
Wrapped
<types>
<schema>

<element name="myMethod"/>
<complexType>
<sequence>
<element name="x" type="xsd:int"/>
</sequence>
</complexType>
</element>

</schema>
</types>
<message name="myMethodRequest">
<part name="
parameters" element="
myMethod"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

<binding .../>
<!-- I won't bother with the details, just assume it's document/literal. -->
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
</myMethod>
</soap:body>
</soap:envelope>
没有编码信息。
出现在 soap:body 中的每项内容都是由 Schema 定义的,所以您现在可以很容易地检验此消息的有效性。
方法名又出现在 SOAP 消息中
WSDL 甚至更复杂,但是这仍然是一个非常小的缺点
  相关解决方案