简单 SOAP 消息的另一个变体是附件。对于附件,多年来人们早已耳熟能详,但由于现在某些扩展规范要求使用附件,因此您必须对其进行处理。
二进制数据和 XML
尽管 XML 是基于文本的格式,但却不能忽略实际上是采用二进制进行表示的。因为这样,将会有需要向 Web 服务传递或从其检索二进制信息的情况。
可以采用两种方式中的一种来处理这种情况。第一种选择是将二进制数据实际包含在您的文档中。这种情况的一个例子是将 Microsoft Word 文档另存为 XML 文件时。如果在该文档中嵌入了任何图形,Word 会将其作为二进制数据嵌入到 XML 文档中(采用 Base64 编码)。第二种选择是直接引用该数据,以便处理该文档的 应用程序能够找到此数据。一个极为常见的例子是 Web 浏览器以及其处理从 XHTML 文件引用的图像的方式。XHTML 文本包含一个 img 元素(或者,采用了更为先进的技术,则为 object 元素),该元素包含一个 src 属性,其中有指向实际数据的 URL。应用程序可以随后从该位置加载数据并相应地进行使用。
SOAP 文档也是这样。假如,如果向基于 SOAP 的服务提交了一个图像,有两个选择。可以将该数据嵌入在有效负载中,或可以想办法引用该数据。曾经由于涉及到带宽的一些问题对此进行过讨论。
XML 二进制优化打包
XML 已经比二进制对应项冗长得多了。正因为如此,它将使用更多的带宽。那么,当考虑使用向 XML 文本文档添加二进制数据时的首选方法(将其编码为 Base64)时,会由于两个或更多的因素而导致其尺寸增大,这就带来了一个非常实际的问题。
事实上,在过去的两三年,曾经有很多人强烈地批评缺乏对二进制数据的实时支持,几乎充斥着不满的声音,最终 W3C 开始着手处理这个问题。其工作的成果就是 XML 二进制优化打包(XML-binary Optimized Packages,XOP)。此协议提供了在 XML 文档中可靠地引用外部数据的方法。例如,SOAP with Attachments 规范规定二进制数据可以作为多部分 MIME 文档的的一部分发送,由 XML 数据组成第一部分,而二进制数据作为附加部分添加到其中。这样做的问题在于,尽管您的程序可能知道数据存在,但文档并不知道这一点。同时,还不允许对文档进行选择性优化或对包含二进制数据的现有文档进行回溯处理。
XOP 通过提供一个特殊的机制来改进这种情况,利用这种机制可选择性地提取要优化的信息,将其添加到多部分 MIME 消息中(其中也包括您的 SOAP 消息)并显式地对其进行引用。让我们看一个例子。
例如,假定员工不想将新文章作为文本元素添加,而希望将其作为二进制文档从字处理程序添加。如果将该内容包含在消息体中,将十分混乱,如清单 33 中所示:_
清单 33. 添加二进制文档
<?xml version='1.0' ?> <env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope"> <env:Header> </env:Header> <env:Body> <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms"> <cms:category>classifieds</category> <cms:subcategory>forsale </cms:subcategory> <cms:articleHeadline><cms:articleHeadline> <cms:articleText>wvetwenptiubnweoirntuwopeirt4m[456n09ew7nv sa0tv043u6y304o5mu60ew9rebtm45bm4-69nw-0er9utnv3094nb-26204 95u6-49kv6-m34956h-wb09emjb-0n67u-340v,=qw-enr7w8b64b03278- ANDLOTSMOREBASE64ENCODEDDATAHERE</cms:articleText> </cms:addArticle> </env:Body> </env:Envelope> |
相反,XOP 规定对数据进行提取,然后使用一个引用其新位置的 Include 元素将其替换,如清单 34 中所示。
清单 34. 使用 XOP
MIME-Version: 1.0 Content-Type: Multipart/Related;boundary=MIME_boundary; type="application/xop+xml"; start="<soapmsg.xml@daily-moon.com>"; start-info="text/xml" Content-Description: An XML document with binary data in it --MIME_boundary Content-Type: application/xop+xml; charset=UTF-8; type="text/xml" Content-Transfer-Encoding: 8bit Content-ID: <soapmsg.xml@daily-moon.com> <env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope"> <env:Header> </env:Header> <env:Body> <cms:addArticle xmlns:cms="http://www.daily-moon.com/cms"> <cms:category>classifieds</category> <cms:subcategory>forsale </cms:subcategory> <cms:articleHeadline><cms:articleHeadline> <cms:articleText><xop:Include xmlns:xop='http://www.w3.org/2004/08/xop/include' href='cid:http://daily-moon.com/tbird.doc' /></cms:articleText> </cms:addArticle> </env:Body> </env:Envelope> --MIME_boundary Content-Type: application/vnd.oasis.openoffice Content-Transfer-Encoding: binary Content-ID: <http://daily-moon.com/tbird.doc> // binary octets for the word processing file --MIME_boundary-- |
请注意,Include 元素中指定的位置与 Content-ID 减去协议 cid: 的值匹配。现在要发送的是此消息,而不是纯文本 SOAP 消息。
SOAP、二进制数据和 Axis2
在 SOAP 文档中使用 XOP 的过程称为 MTOM(即 SOAP 消息传输优化机制——Message Transmission Optimization Mechanism)。Axis2 提供了使用 SOA 数据的这个方法的支持,但必须确保对应用程序进行了恰当配置。
具体来说,您必须在 axis2.war 文件内的 axis2.xml 文件中启用此支持(请参见清单 35)。
清单 35. 将 XOP 与 Axis2 一起使用
<axisconfig name="AxisJava2.0"> <!-- ================================================= --> <!-- Parameters --> <!-- ================================================= --> <parameter name="hotdeployment" locked="false">true</parameter> <parameter name="hotupdate" locked="false">true</parameter> <parameter name="enableMTOM" locked="false">true</parameter> <!-- Uncomment this to enable REST support --> <!-- <parameter name="enableREST" locked="false">true</parameter>--> <parameter name="userName" locked="false">admin</parameter> <parameter name="password" locked="false">axis2</parameter> ... |
如果有必要,可以提取 axis2.war 文件,进行此更改,然后将其重新压缩成 .war 文件。
要替换 Axis2 应用程序,请使用清单 36 中所示的 URL 访问 Geronimo 控制台。
清单 36. Geronimo 控制台
http://localhost:8080/console
作为 system/manager 登录,并单击 Application>Web App WARs,然后卸载并重新安装 Axis2 应用程序。(请记住,执行此步骤后,必须重新加载 Web 服务。)
以编程方式使用 MTOM 不在本教程的讨论范围之内,但可以在参考资料部分获取有关此主题的更多信息。只是要注意,在 Axis2 的 0.95 版之前的版本上可能不会按照预期工作,因为该版本中包含了 SOAP with Attachments API for Java (SAAJ) 实现。
(作者:佚名责任编辑:方舟)