SOAP与RDF:超越远程过程调用

日期: 2010-07-01 来源:TechTarget中国 英文

  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模型的图解

图 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

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐