SOAP是用来在较低层的因特网协议之上运载XML有效负载的传输协议。早于 1.2 版本的传输规范内建在所建议的XML编码中,这是为了适应编程语言构造的序列化。这样的编码是被称为远程过程调用(RPC)系统的主要部分,它们有一个共同的目标,就是使对远程计算机发出的请求看起来象是本地过程调用一样。RPC编码的其它示例是源自“典型”RPC(在 RFC 1014 中定义)的“外部数据表示”(External Data Representation(XDR))以及源自CORBA的“通用数据表示”(Common Data Representation(CDR))。作为以这种关系捆绑编码的结果,SOAP表现出勿庸置疑的应用程序编程的能力,但是它的用途对于通用的数据交换似乎值得怀疑。
这些早期的对SOAP的偏爱引发了众多的争论。首先,混合传输和数据编码规范似乎是非常杂乱的通信方法,并且似乎公然违背实行几十年的网络互联的分层协议。毕竟,HTML标记的规范没有嵌入到HTTP规范中。其次,选择将像RPC这样的编码放在突出的地位使SOAP处于比较尴尬的境地;它几乎不比以前的XML RPC机制更有表现力,然而由于XML的冗长以及HTTP、SMTP等这样的更一般的体系架构,它实际上只能保证更小的有效性。作为下一代RPC,SOAP带来的唯一好处似乎只是统一了Microsoft和CORBA阵营;这是很重要的,但是这当然不是说SOAP看起来很有前途。
SOAP-as-RPC的一个重要的负面后果是,这样的系统一般来说完全不适合Web服务的下一代EDI的长远目标。如果Web服务成为网络上商业通信新的方法,那么它们似乎将需要在商业和合法请求级别上进行通信的传输机制,而不是在编程语言API级别上进行通信的传输机制。可以确信的是,和其它几个具有影响力的组织使用SOAP一样,ebXML倡议(其长远目标是使用XML来打造用于国际电子商务通信的系统)最初拒绝使用SOAP。
从那以后事情有所平息。SOAP 1.2一定程度上减少了对特殊编码的依赖(将其归入单独的“附件”这部分),现在大多数开发者都在使用SOAP,包括ebXML。大多数 SOAP 实现仍然专门使用特殊的SOAP编码,但是有迹象表明事态将更开放,由于插件体系结构的缘故将有更广泛的编码选择,能够解决更多的通信问题。这样的一个问题是元数据的交换,包括帮助确定在其它XML文档(使用SOAP传输)中用到的语义的元数据。
“资源描述框架”(Resource Description Framework(RDF))是一个建模系统,该系统具有解决这种元数据交换的一些功能。本文将看看怎样一起使用RDF和SOAP来编码这种元数据,而且要看看在不需要转换成SOAP编码的情况下,怎样直接传输以RDF编码的数据实例。本文要求对SOAP和RDF比较熟悉。另请参阅IBM developerWorks XML专区的Thinking XML专栏,以了解正在进行的与知识管理相关的RDF和其它XML技术的讨论。
好载体RDF
首先,我将说明如果借助SOAP将RDF从一个系统传到另一个系统,您能做些什么。我将以XML专区上我的Thinking XML专栏中的一个正在讨论的问题跟踪器工程作为示例。假设我们希望交换添加到通往远程主机的系统的问题的详细信息。这可能是分散、分布式问题跟踪器的基础。RDF序列化中,一个问题的示例如 清单1所示。
清单 1:RDF/XML序列化
以下是引用片段: <?xml version=”1.0″?> <rdf:RDF xml:base=”http://rdfinference.org/versa/issues”> <it:issue rdf:ID=”0101″> <dc:relation rdf:resource=”http://rdfinference.org/versa/0/2″/> <dc:identifier>0101</dc:identifier> <dc:creator rdf:resource=”mailto:uche.ogbuji@fourthought.com”/> <dc:date>2002-01-27</dc:date> <dc:title>Data type conversions</dc:title> <dc:description>Not all the data type conversions listed make sense. In particular the question of how to convert numeric types to resources and vice versa require much thought.</dc:description> </it:issue> </rdf:RDF> |
这是一个由Web资源引起的示例问题。问题本身由URI http://rdfinference.org/versa/issues#0101标识。这个URI通过取文档的基本 URI,再在代表该问题的这个类型节点添加rdf:ID属性所给的片断来确定。使用xml:base属性给出文档的基本URI(或者更精确地说,是文档元素的基本URI,因此是类型节点元素本身的基本URI),为 http://rdfinference.org/versa/issues。然后,您要写几个关于问题本身的语句,最重要的是,使用Dublin Core的dc:relation 元数据标记给出问题引用的资源。您还要提供一个标识符(该标识符是问题完整的 URI 的缩写,只是为了友好显示这个问题)、问题的创建者、提交日期、简要标题以及详细描述。
请记住这是RDF,因此XML序列化不是最重要的事,最重要的事是这个示例问题怎样转换为抽象的RDF模型。例如, 图 1,由Triclops(一个RDF可视化工具,随4Suite 0.12.0 alpha 1或更近的版本提供)生成(警告:这个工具生成相当大的一张图)。您还可以使用Dan Brickley的在线RDF可视化程序生成一个类似的图。
图 1:样本RDF模型的图解
现在我来看看在SOAP消息中传输这种模型的两种方式:第一种是通过转换为SOAP编码来传输,另一种是直接以RDF编码来传输。
使用SOAP编码
首先,您必须计划传输的方法。您所定义的RDF是数据束,其思想是将这个数据束放在消息中传输,您按照我们期望接收方处理数据的方式来命名。在本例中,您通知远程服务器:这里有一个新的问题要跟踪。因此,我把这个方法叫做newIssue 。请注意,由于现在您正在使用SOAP编码,所以您也可能使方法名适合于带有用于RPC的SOAP绑定的编程语言。
然后,您不得不找到传输这个新问题对象的方法。您通过传输这个新对象的标识及它的属性来完成。本质上是,您将新问题对象的每个属性去掉,并且将其转换成消息参数。因为SOAP编码很注重类型信息,所以您必须用一个类型修饰每个参数(请参阅 清单 2)。
清单 2:newIssue SOAP消息
以下是引用片段: <?xml version=’1.0’ ?> <env:Envelope > <env:Body> <itsoap:newIssue env:encodingStyle=”http://www.w3.org/2001/12/soap-encoding” > <dc:identifier xsi:type=”xs:nonNegativeInteger”>0101</dc:identifier> <dc:relation xsi:type=”xs:anyURI”>http://rdfinference.org/versa/0/2</dc:relation> <dc:creator xsi:type=”xs:anyURI”>mailto:uche.ogbuji@fourthought.com</dc:creator> <dc:date xsi:type=”xs:date”>2002-01-27</dc:date> <dc:title xsi:type=”xs:string”>Data type conversions</dc:title> <dc:description xsi:type=”xs:string”>Not all the data type conversions listed make sense. In particular the question of how to convert numeric types to resources and vice versa require much thought.</dc:description> </itsoap:newIssue > </env:Body> </env:Envelope> |
SOAP编码规则要求,所有的值放在元素的内容中,这包括RDF中标记作为资源的值,因此给定了数据类型anyURI 。请注意,这允许这些值可以是URI引用,也可以是完整的URI(也就是说,相对URI和片断都可以)。如果所有这样的消息都是这种格式,那么通过给消息元素定义一个 XML模式定义,您可以避免必须重复数据类型,之后,它可以放在“Web服务描述语言”(WSDL)元素中,或者以一些其它的非常规方式进行通信。 清单 3和 清单 4是这种模式的片断(省略了根元素和名称空间声明)(分别给出是因为它们占用不同的目标名称空间)。
清单 3:newIssue SOAP消息元素的模式片断
以下是引用片段: <!– with target namespace = http://rdfinference.org/schemata/issue-tracker/soap –> <xsd:element name=”newIssue”> <xsd:complexType> <xsd:all> <xsd:element ref=”dc:identifier”/> <xsd:element ref=”dc:relation”/> <xsd:element ref=”dc:creator”/> <xsd:element ref=”dc:date”/> <xsd:element ref=”dc:title”/> <xsd:element ref=”dc:description”/> </xsd:all> </xsd:complexType> </xsd:element> |
清单 4:newIssue SOAP消息参数元素的模式片断
以下是引用片段: <!– with target namespace = http://purl.org/dc/elements/1.1# –> <xsd:element name=”identifier” type=”xsd:nonNegativeInteger”/> <xsd:element name=”relation” type=”xsd:anyURI”/> <xsd:element name=”creator” type=”xsd:anyURI”/> <xsd:element name=”date” type=”xsd:string”/> <xsd:element name=”title” type=”xsd:string”/> <xsd:element name=”description” type=”xsd:string”/> |
可以将这些片断简化为清单 5。
清单 5:没有内联类型装饰的newIssue SOAP消息
以下是引用片段: <?xml version=’1.0’ ?> <env:Envelope > <env:Body> <itsoap:newIssue env:encodingStyle=”http://www.w3.org/2001/12/soap-encoding” > <dc:identifier>0101</dc:identifier> <dc:relation>http://rdfinference.org/versa/0/2</dc:relation> <dc:creator>mailto:uche.ogbuji@fourthought.com</dc:creator> <dc:date>2002-01-27</dc:date> <dc:title>Data type conversions</dc:title> <dc:description>Not all the data type conversions listed make sense. In particular the question of how to convert numeric types to resources and vice versa require much thought.</dc:description> </itsoap:newIssue > </env:Body> </env:Envelope> |
发送原始RDF
我在本文开始部分讨论过,没有理由为了使用SOAP,而一定将SOAP消息转换为RPC形式。如果您不是一定需要将RPC集成到其它系统中,那么在恰当的时候,您可以采用更自然的措施,使用发送数据并且使远程系统可以自由处理数据的声明性方法。还没有官方的面向SOAP的RDF编码,而本文的讨论基于RDF和SOAP的约定和规定。
最简单的方法是仅仅使rdf:RDF元素作为SOAP体的单个顶层元素,说明见 清单 6。
清单 6:
以下是引用片段: <env:Envelope > <env:Body> <rdf:RDF env:encodingStyle=”http://rdfinference.org/rdfws/soap-encoding” > <it:issue rdf:about=”http://rdfinference.org/versa/issues#0101″> <dc:relation rdf:resource=”http://rdfinference.org/versa/0/2″/> <dc:identifier>0101</dc:identifier> <dc:creator rdf:resource=”mailto:uche.ogbuji@fourthought.com”/> <dc:date>2002-01-27</dc:date> <dc:title>Data type conversions</dc:title> <dc:description>Not all the data type conversions listed make sense. In particular the question of how to convert numeric types to resources and vice versa require much thought.</dc:description> </it:issue> </rdf:RDF> </env:Body> </env:Envelope> |
所用的编码标识,http://rdfinference.org/rdfws/soap-encoding是非规范化的,其本质是,直接将RDF/XML的嵌入部分编码到SOAP消息体中。消息形式和一般形式的一个关键的区别是,rdf:about用来识别问题资源,但是,它没有内联地使用标识来声明。这是序列化用于 SOAP 传输的RDF模型的一个很重要的原则:避免内联声明。假如我们可以使用xml:base修改标识的基本位置,那么这样的原则看起来并不是必需的,但是很难想象出内联传输的资源的生命周期和所有权的清晰语义。请注意,内联声明并非在所有的情况下都能避免。例如,匿名资源(也就是空节点)可能需要作为描述的一部分被传输,根据定义,它们没有恰当的标识符。
结束语
当谈到SOAP和RDF怎样能够进行互操作时,还有其它的方法和思想,事实上这是人们一直很感兴趣的主题,RDF用户怎样发现Web服务以及Web服务怎样找到RDF用户。更通用的用于序列化基于XML数据的系统当然会使全世界的Web服务更丰富。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
API设计:如何正确开发应用程序接口
在交互组件化软件的世界里,没有比让组件之间以及组件与移动设备和浏览器之间进行连接的应用程序接口(API)更重要的东西了。
-
REST vs. SOAP:如何挑选最好的Web服务
在应用没有任何服务器端的组件情况下,有没有可能直接通过我的应用数据库直接使用这些Web服务?
-
BEST:SOAP/XML和REST的替代方案
虽然拥有大量的机架服务器,以及大量软件开发人员的组织,基于web和集成服务的SOAP和REST很适合他们,但也会出现问题。
-
REST和SOAP 谁使移动应用最受益?
你应该听说过REST,如果在移动应用开发中使用REST,而不是使用SOAP,最大好处是什么?