王朝网络
分享
 
 
 

消息传递:传递XML的困惑

王朝other·作者佚名  2008-05-21
宽屏版  字体: |||超大  

需要帮助来理清 XML 消息传送协议吗?本文回顾了不同主流的传输层协议并比较了它们如何在不同应用间可靠地传送 XML。您将看到如何将 XML-RPC, SOAP, WDDX, ebXML 和 JMS 作为 XML 传输协议的概要介绍以及示例代码。

在 XML 出现的三年中,在开发人员中讨论甚至争论最为激烈的是词汇(vocabulary)和方言(dialect) -- 换而言之,在双方间使用的语言以及如何展现这些数据。当一些 前瞻的思想家早在 1998 年开始考虑解决传递 XML 数据这个需求,而仅在七个月前 XML 开发人员的重点开始从数据解析转移到根本的如何在不同参与者之间以一种有意义并 可靠的交换方式来传递 XML。本文探讨了目前在 XML 传递中所出现的先进的协议,它们所解决的问题以及它们之间的关系。

消息传递的需求

您可能会问:"对 XML 我们为何需要一种传递方式?我们不是已经有 HTTP 了吗?" 让我们来看一个 XML 的典型应用来解释这个问题:供应链集成。在此场景下, 价格更改信息可能从每个供应商那传递到一些零售商,而每个零售商反过来可能想在新的价格上下订单。XML 允许开发人员创建格式正确的文档来描述交易。但是您如何通过编程来传递这些文档并对它们的接受做出响应呢?

每个发送方,无论是零售商或是供应商,必须以一种可以被传递的格式对文档编码然后被接受方理解和处理。每个供应商必须管理零售商列表以及他们的网络地址。每个 供应商也需要确保每个零售商接受到他所发送的所有交易。但如果有一个零售商断线了,或者因特网的路由失败了?供应商可能需要继续尝试与所有的接受方通讯直到交易信息 能被成功发送。如果供应商在零售商试图下订单时同样不能被访问到呢?显然系统需要提供对关键交易的存储直到所有接受方确认它们的接受。同样,系统必须确保所有参与 交易的各方是被允许的而且经过认证,而在传递过程中每个交易是完整的。

HTTP 不能提供对这些问题的任何帮助。要么应用程序自己吸收支持这些协调、安全和可靠性的开销 -- 或者干脆不支持。而这在 B2B 中是最简单的情况。 设想在多个企业间协调复杂的交易!显然需要一些标准的传递方式。

协议,协议,还是协议!

尽管开发界对 XML 传递问题的兴趣刚刚产生,经过我们统计已经有不下 15 种 XML 通讯协议了。W3C 组织的 Eric Prud'hommeaux 和 Ken Macleod 调查了这些协议,并在 W3C 站点上提供了一个非常好的总结(参见 参考资料)。在其总结中,XML-RPC、SOAP、WDDX 和 ebXML 作为 最可能直接影响 XML 传递未来发展的技术。

XML-RPC 和 SOAP: XML 序列化(serialization) 及 RPC over HTTP

一开始,先出现 XML-RPC。在 1998 早期由 Userland 的 Dave Winer, DevelopMentor 的 Don Box 以及 Microsoft 开发,XML-RPC 提供了一个非常简单使用在 HTTP 上传递 XML 的 RPC 机制。 XML-RPC -- 或可被更为准确称为 Dave Winer,它的创造者 -- 几乎是独自意识到 XML 可不单单作为一种通用的文档格式,而可以成为基于标准的事务处理基础。 一些 XML-RPC 的实现在今天已被使用。这些实现,基于相当广泛的技术例如 Java 技术、COM、Perl、Tcl、Python、PHP 以及 AppleScript,保证了这种机制具有它的设计人员所期望的是平台和语言无关。 他们也对一些批评者的意见 - SOAP (XML-RPC 更常见的后代)是一个 Microsoft 独有的技术,作了强有力的反驳。 也许迄今为止对 SOAP 作为一个开放标准最有力的支持是 Apache 组织接受了 IBM 的 SOAP4J 实现最为一个不断更新的开放源码参考实现。

SOAP,就象 XML-RPC,可以被认为是一个基于 Web 对传统分布式对象通讯的抽象。正如在 W3C SOAP 1.1 草稿中所述:SOAP 是一个轻量级的协议用来在非集中的分布式的环境中交换信息。它是一个基于 XML 的协议由三部分构成:一个信封 - 描述消息的内容和处理方式, 一套编码规则 - 表示应用定义的数据类型实例,以及表示远程过程调用和响应的约定。

要理解使用 SOAP 如何传递 XML,让我们看一个简单的假设的交易例子。要下一个订单,一个零售商发出一个 OrderItem SOAP 请求给一个供应商。 在简化的例子中,该请求包括物品(Item)信息和一个零售商 ID,以及在 SOAP 响应中返回订单(Order)号码。OrderItem 消息嵌入在一个 HTTP 请求中,其格式如列表 1:

列表 1. SOAP 请求示例

POST /Supplier HTTP/1.1Host: www.somesupplier.comContent-Type: text/xml; charset="utf-8"Content-Length: nnnnSOAPAction: "Some-URI"

557010

1050420459

AMF Night Hawk Pearl M2

Bowling Ball

100

130.95

2000-06-19 10:09:56

在列表 1 中的请求指明来自 Some-URI 命名空间(namespace)的 OrderItem 方法应该在 http://www.somesupplier.com/Supplier 中被调用。 在接受到 该请求后,在 www.somesupplier.com 供应商应用程序根据 OrderItem 执行商务逻辑。SOAP 协议本身不指定或隐含这种处理的方法。 供应商可以运行一个 CGI 脚本、调用一个 Servlet 或者执行任何其它的进程来产生对该请求对应的响应。该响应可能以 一个包含处理结果的 XML 文档形式 -- 在这种情况下就是,零售商所下订单(order)的订单号(order number)。 响应中不包括 SOAP 独有的头(header)信息,但结果将被放置在一个元素中,其名称与该方法名加上 "Response" 后缀相匹配,参见列表 2:

列表 2. SOAP 响应示例

HTTP/1.1 200 OKContent-Type: text/xml; charset="utf-8"Content-Length: nnnn

561381

SOAP 支持所有在 W3C 指定中的 XML Schema 草稿第二部分:数据类型中"内置(Built-in)数据类型"章节的数据类型,以及一些基于结构和数组的复合类型。

正如在 SOAP 常见问题(参见 参考资料)所指出的,SOAP 本身不解决高层的分布式对象问题,例如对象激活(Object Activation)或者生命周期管理(Lifecycle Management)。 更重要的是在 XML 传输环境下,SOAP 本身没有指明消息传递的语义 -- 例如异步通讯、服务质量和队列 -- 这些为基于因特网交易所要求的功能。目前对 SOAP 消息的处理要求应用本身能够理解和实现要使用的传递语义(一对一、请求/响应、广播等等),以及应用节点在这些语义下的角色。 SOAP 信封本身甚至不包含关于to impart to the 接受方应用节点的信息。这些限制是隐含在 SOAP 期望的范围中而且可以由选择使用 SOAP 的高层协议来解决。即使有人要在 SOAP 之上搭建一个实际的消息传递模型,它的核心 依赖于一个基于 HTTP 的 RPC 机制可以防止风险。自从今年春天 SOAP 版本的发布,出现许多有关其安全性的讨论,包括 Larry Masinter 在 SOAP 邮件列表中提交的一个对基于 HTTP 的 RPC 产生的风险探讨。

WDDX: 不使用 RPC 绑定的序列化

SOAP 的另一个选择是 Web 分布式数据交换(Web Distributed Data Exchange/WDDX)。由 Allaire 公司在其语言技术部经理(Manager of Language Technology) Simeon Simeonov 的指导下开发,WDDX 提供了一个 在 HTTP 之上交换复杂数据结构的机制。WDDX 声明的目标是“提供一个更类似 Web 的方法在不同的网络实体间传送结构化数据对象,而不需要将开发 Web 应用的编程方法从面向页面改变到面向对象。 ”于 1998年晚期出现的 WDDX 从两点上根本区别于 XML-RPC 和 SOAP。 首先,它序列化的方法是基于结构的而不是基于对象的 -- 基于对象的方法可能有争议地更适合通用地表达商务交易,以及映射到基于 EDI 的交易。 正如它的创造者所指出的,它的缺点是它不能被用来交换具有复杂关系的对象实例。另一个更明显的是,WDDX 从根本上不是基于 RPC 语义的。

WDDX 通过两个方面被实现:WDDX DTD 和一套序列化和反序列化的模块来负责原始语言数据结构与 XML 间的相互转化。 当一个应用将数据结构转化为 WDDX 时,一个 WDDX 包被创建。WDDX DTD 可以被用来验证 WDDX 包。WDDX 使用一个简单的聚集(pure aggregation)模型来序列化数据; 它没有处理对象引用或关系的机制。让我们参看一个示例的 WDDX 包,仍然是对一件物品下订单的请求:

列表 3. WDDX 包示例

557010

1050420459

AMF Night Hawk Pearl M2

Bowling Ball

100

130.95

200-06-19T10:09:56

除在上面例子中显示的 number、string、dateTime 和 structure 类型外,WDDX 也支持 Boolean、数组(array)和记录集合(record set)。类似 SOAP,WDDX 本身缺乏 在多方间处理商务交易的高层语义,但它不强求 SOAP 的同步语义。在 WDDX 中的序列化机制为了可交互性很可能使用高层协议的实现,而不依赖于 SOAP 所隐含的面向 RPC 的实现。

Allaire 已经将 WDDX 规范开放给广大的开发人员。WDDX 在 ColdFusion 中已经被实现,在 WDDX Web 站点(参见 参考资料)上找到 一个支持 Java 语言、JavaScript、Perl 和 COM/ASP 的 SDK。

从序列化和 RPC 演变到真正的交互

如果我们将 XML-RPC、SOAP 和 WDDX 考虑成基本的在 HTTP 上序列化和传递 XML 编码数据的技术,那 ebXML 的计划是要在解决的思路上有显著的突破。 由联合国贸易促进和电子商务团体(The United Nations body for Trade Facilitation and Electronic Business/UN/CEFACT)和结构化信息标准促进组织(Organization for the Advancement of Structured Information Standards/OASIS)的共同倡议,电子商务 XML(Electronic Business XML/ebXML)的目标是“提供一个开放的基于 XML 的基架,使得各方 以一个可互通、安全和一致的方法使用电子商务。”一个非常宏伟的目标,但是我们可以确信 ebXML 可以实现它。 由八个工作组构成,每个关注于一个特定的技术或组织,这个倡议已经迅速建立起动力。ebXML 已获得所有重要的商业、服务业、贸易业和技术界 有影响的实体的支持和积极参与。

在我们对 XML 传递讨论中特别之处是 ebXML 传递、路由和打包(Transport, Routing and Packaging/TR&P)开发队的工作。尽管这个工作仍处于规范制订流程的早期阶段,其所代表的发展方向给出了对未来基于 XML 贸易的预见。 迄今为止,工作组已对公众发表了如下文档:概栏和需求文档、消息信封规范和消息头规范草稿版(strawman message-header specification)。

消息信封是 MIME 编码的并且包括一个头信封(header envelope)和一个负载信封(payload envelope)。头信封包括信息头(参见列表 4),路由信息和数字签名。负载信封 可以包含多个实体节(body segments) (参见列表 5),每个节可能是不同的格式(尽管 ebXML 框架是设计成主要来支持传递 XML 的, 开发队伍也意识到需要在一个消息中嵌入其它类型,例如 JPEG 或 PDF 文件)。

列表 4. ebXML 信息头示例

1.0

Request

OTA

CustProfileUpdate

列表 5. 部分 ebXML 消息实体节 (body segment)

ebXML 消息传递的有趣的一面是它要支持在多方交易处理中必须的高层语义。这些语义包括 一对一以及一对多路由模型,对多方回路文档交换的支持,以及根据消息头属性的服务质量确定。

与其它开放的消息传递规范类似,ebXML 规范很可能保持对底层链接协议的无关。可用的协议包括 HTTP、FTP、SMTP 甚至 SOAP。 在 ebXML 开发界有一些讨论认为尽管 ebXML 将会保持与传输协议无关,它很可能倾向于使用 SOAP 作为链接协议的选择。

今年五月在布鲁塞尔一个工作组在 ebXML 大会上展现了一个 ebXML 的原型系统。采用了 Open Travel Alliance (OTA) 的 DTD,该原型系统成功地展示了 一个基于 HTML 的门户站点通过基于 HTTP 和 SMTP 在多个服务供应商之间协调异步的交易能力。Apache 组织已经宣布他们将开发一个用 Java 代码实现的 ebXML 参考实现。

消息传递解决方案

面向消息的中间件(Message-oriented middleware/MOM)已为在企业之间提供数据交换有几十年了。MOM 解决方案提供的语义非常丰富,并提供了多方交易所必需的高层交互模型和服务质量(Quality of Service)。 直到最近,实现 MOM 的软件,例如 MQSeries,变得不够开放而且不能很好适应因特网环境下的交易。 而这随着 JavaSoft 公司发布 Java 消息服务(Java Message Service)规范后有所改变,它被消息基架和应用服务器开发人员所广为接受。

JMS:真正开放的 MOM

JavaSoft 公司的 Java 消息服务(Java Message Service/JMS) 规范代表了在基于标准的消息中间件领域的领先概念。JMS 包含了一个 API 以及一个提供了诸如持久、验证和事务语义的消息服务。

主要通过 Sun Microsystems 公司的 Mark Hapner 的努力,JMS 规范提供了 一个通用的消息模型能够支持不同的异步和同步通讯机制。 主要的机制有发布/订阅(publish/subscribe 或 pub/sub)以及点对点(point-to-point)。Pub/sub 提供了一个一对多 模型,一个客户端应用发布消息给其他客户端所订阅的主题。我们的 pub/sub 的例子是一个供应商将价格信息分发给他的零售商。点对点的例子是,一个客户端 发送消息到一个队列中,而一个或多个客户端依次获得这些消息。有了 JMS,这两种模型的编程模式几乎是相同的。

列表 6 中展示了一个使用 JMS 来获得一个消息系统的联接并利用 Progress SoniceMQ 中 JMS 的实现来发送一个包含 XML 文档的文本消息。

列表 6. 通过 JMS 发送 XML

private static final String DEFAULT_BROKER_NAME = "localhost:2506";private static final String DEFAULT_PASSWORD = "password";private static final int

MESSAGE_LIFESPAN = 1800000;

// 毫秒 (30 分钟)private javax.jms.QueueConnection connect = null;private javax.jms.QueueSession session = null;private javax.jms.QueueSender sender = null;/** 建立 JMS 客户端来发布消息。*/private void sender( String broker, String username, String password, String rQueue, String sQueue){

// 建立联接。

try {

javax.jms.QueueConnectionFactory factory;

factory = (new progress.message.jclient.QueueConnectionFactory (broker));

connect = factory.createQueueConnection (username, password);

session = connect.createQueueSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);

}

catch (javax.jms.JMSException jmse) {

System.err.println("error: Cannot connect to Broker - " + broker);

jmse.printStackTrace();

System.exit(1);

}

// 建立发送方队列。

try {

if (sQueue != null) {

javax.jms.Queue sendQueue = session.createQueue (sQueue);

sender = session.createSender(sendQueue);

// 现在队列已经建立,开始联接。

connect.start();

}

}

catch (javax.jms.JMSException jmse) {

jmse.printStackTrace();

exit();

}

try

{

// 接受所有标准输入并将其作为消息发送。

java.io.BufferedReader stdin =

new java.io.BufferedReader( new java.io.InputStreamReader( System.in ) );

if (sQueue != null)

System.out.println ("

Enter text you want XML-packaged as the message content to"

+ " queue "" + sQueue + ""." +

"

Press Enter to send each message.

");

else

System.out.println ("

Press CTRL-C to exit.

");

while ( true ) {

String s = stdin.readLine();

if ( s == null )

exit();

else if ( s.length() > 0 &sQueue != null) {

// 注意 XMLMessage 是 Progress Software 的独有扩展;

// 在一个最普通的 JMS 实现中您应该将 XML 放到一个 TextMessage 对象中。

progress.message.jclient.XMLMessage xMsg = ((progress.message.jclient.Session) session).createXMLMessage();

StringBuffer msg = new StringBuffer();

msg.append ("

");

msg.append ("

");

msg.append ("

" + username + "

");

msg.append ("

" + s + "

");

msg.append ("

");

xMsg.setText( msg.toString() );

// 对 PERSISTENT 消息通常使用队列。

// 将消息包存 30 分钟 (1,800,000 毫秒)。

sender.send( xMsg, javax.jms.DeliveryMode.PERSISTENT, javax.jms.Message.DEFAULT_PRIORITY, MESSAGE_LIFESPAN);

}

}

}

catch ( java.io.IOException ioe ) {

ioe.printStackTrace();

}

catch ( javax.jms.JMSException jmse ) {

jmse.printStackTrace();}

使用 JMS 架构的一个明显优点是其可靠性。在 JMS 中,一个发送方(sender)应用程序可以指定一个消息必须被保存在一个代理管理(broker-managed)的数据池中直到所有订阅(subscribed)的 接受端收到它。在接受端,订阅可以是持久的,意味着一个客户端一旦联接到消息代理后将自动接受发送给其所订阅主题的消息,并包括当客户端断线时所有被发送的持久(persistent)消息。JMS 也支持低层消息确认 -- 自动(automatic)及编程(programmatic) -- 以及请求-响应机制以及事务处理语义来打包大的数据集。

JMS 规范并不指定在消息节点间所使用的通讯低层协议,来保证应用开发人员不用与其细节打交道。一个特定的 JMS 实现可能提供基于 TCP/IP、HTTP、SSL 或者其它的协议。

尽管 JMS 不是专门设计成来传递 XML,在实际应用中由于它对消息交换高层语义的支持使得它成为一个传递 XML 非常好的方法。JMS 供应商早已开始将 XML 处理作为他们产品的一部分来提供,解决方案开发商现在已经将 广泛的 XML 应用 -- 从 EAI 到 B2B 供应链集成 -- 架构在 JMS 消息基架上。JMS 的架构师已经意识到 XML 和 JMS 集成的力量,您可预见到未来这两种技术更为紧密的合作。

总结

在快速查看了我们可有的不同选择后,我们可以开始对它们在传递 XML 中的作用作出一些总结。SOAP 和它的兄弟 XML-RPC 提供了一个序列化(serialization)方案,并在在 HTTP 上提供了传输协议最适合支持通常在分布式对象运算中常见的同步机制。尽管在 SOAP 之上可提供更高的协议,但是其依赖于的 RPC 机制会带来一些天生的缺陷。WDDX 提供了一个更面向文档的序列化方案,而不受远程过程调用的影响。这个序列化方案可能可以用在更高层的协议中。ebXML -- 指定中的 XML -- 将定义在多方商务交易中的高层语法,同时不依赖于低层的传输协议。 Java 语言基于 JMS 的消息传递提供了一个与平台无关提供了大多数高层语义的消息传递实现,并且与低层的传递协议无关。它在今天已被广泛使用,通过传递 XML 来解决在企业内部及跨因特网的 EAI 以及 B2B 应用问题。

要理解使用 SOAP 如何传递 XML,让我们看一个简单的假设的交易例子。要下一个订单,一个零售商发出一个 OrderItem SOAP 请求给一个供应商。 在简化的例子中,该请求包括物品(Item)信息和一个零售商 ID,以及在 SOAP 响应中返回订单(Order)号码。OrderItem 消息嵌入在一个 HTTP 请求中,其格式如列表 1。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有