在写这篇文章的时候,大多数的Web服务由简单的信息交换组成:客户端连接到Web服务器端,并发送一条消息给服务端。Web服务端处理客户端的请求并发送回应给客户端。这个简单的请求/回应模式,模拟了HTTP协议帮助客户端/服务器端交互的过程。同样由于HTTP,Web服务信息的交换经常必须包含二进制的内容。比如图像,文档或者声音片段。这篇文章介绍了使用SAAJ1.2(SOAP with Attachements API for Java 1.2)来发送和接收二进制内容Web信息。
在深入到传送二进制Web服务内容的复杂机制前,值得指出的是:简单的请求/回应类型的Web服务,与客户端/服务器端的远程过程调用(RPC)方式不同。在RPC中,服务器给出一个类似API的接口。而客户端通过使用远程调用服务的API,传递必要的参数和接收调用值来启用一个服务。
基于XMl的RPC调用类似在OO系统中调用一个对象一样。事实上,当你用基于XML的JAVA API工作时(Java API for XML-based RPC简JAX-RPC),你总是觉得在跟Java对象工作,而不是跟XML文档工作。JAX-RPC能让你把Web服务看作远程对象,这很像Java RMI(Remote Method Invocation)。JAX-RPC运行时把高层次的OO方法调用转化为远程Web服务需要XML文档。虽然RPC类型的Web服务通常能提供更便捷的编程模型,但是RPC调用也必须依赖更低的消息层来完成组成远程调用XML信息交换。
对于有些Web服务来说,直接在低级别的消息层编程通常是很有用的。例如,如果你想调用一个处理订单的文档并返回收据,对这样的Web服务,你能够很容易地把文档交换模块化为一个请求/回应的信息交换。替代远程方法调用的是,你将构建XML信息,直接发送这些信息到Web服务,如果有的话,还会处理服务的XML回应。由于SOAP为Web信息服务定义了公共的信息格式,你需要构建符合SOAP格式的信息,并且,一旦服务有回应,就要把这些SOAP回应信息解析成你的程序所能理解的格式。
SAAJ提供了一个能方便地构建和读取SOAP信息的库,这个库还允许你通过网络接收和发送SOAP信息。SAAJ定义了javax.xml.soap包。在这个包里面的类组成了最初的JAXM(Java API for XML Messaging),但是最近他们被分离出来成为单独的API。JAXM依赖于SAAJ来构建和处理SOAP信息,并且依赖SAAJ来增加信息的可靠性和增加其他的XML信息特征。尽管SAAJ是J2EE的一部分,JAXM却不是。这篇文章聚焦于SAAJ中最有用的一个方面:就是SAAJ捆绑二进制内容到SOAP信息的能力。
使用附件的好处 尽管SOAP的设计核心集中在信息中封装XML文档,但是,SOAP的附件特征扩展了SOAP所能包含的信息,除了普通的SOAP部分,还可以包括0个到多个附件,如图1所示。每一个附近都由一个MIME类型定义,并且能采用任何的二进制流内容。
图1:带有附件的SOAP信息 当客户端希望传送二进制数据的时候,SOAP的附件特征是非常有用的,比如传送图像,音频数据给一个Web服务。如果没有SOAP附件,发送一个二进制信息会困难很多。比如,一个客户端的SOAP信息传送二进制文件的URL地址。那么,客户端不得不操作一个HTTP服务器,来让Web服务找到这个二进制文件。这会给Web服务的客户端造成过度的负载,特别是当客户端运行在资源有限的设备中,比如数码相机或者扫描仪。SOAP的附件能力使得任何的Web服务客户,能够在SOAP信息里直接传送内嵌二进制文件的SOAP信息。
SOAP附件,已被证明能很方便地与网络站点入口交互。考虑这样一个现实中的房产代理网络,它需要发送房子的介绍和照片到房产查询中心入口。如果这个入口操作一个servlet来让带附件的SOAP信息置入,一个房产代理可以用几个SOAP信息更新它的列表,包括这些房子的照片。SOAP信息体可能嵌入了房子所有权的介绍,并且SOAP附件能带有房子图片文件。在这样的情况下,当一个入口操作servlet接收了这种信息,它就能返回一个认证文档,表明了在入口的发布的有效性。图2说明了这样的一个Web服务。
房产代理的WEB服务,使用了带附件的SOAP信息