对于JMS、XML和异构企业讲解
如今,大多数计算环境更多地是由不同平台组成,而不是固守任何一个平台。 Java 消息服务 (JMS) ,与可扩展标记语言 (XML) 一起,满足了这种异构环境集成的愿望。这篇文章演示了如何使用 JMS 来创建基于 XML 的消息并将这些消息同样分发到 Java 和非 Java 应用程序。
经过几年构建、扩展和维护庞大的分布式应用之后,程序员逐步体会到平台无关的行为和平台无关的数据的好处了。
Java 编程语言已经向满足平台无关的行为(尽管例如 TCL 这样的脚本语言在一段或更长时间内还受到关注)的需要迈进了一步。而且 XML(可扩展标记语言)正在成为开放、平台无关的数据解决方案的中坚力量。
本文演示了在与 Java 消息服务 (JMS) 一起使用的情况下,XML 如何满足平台无关的数据的愿望。
消息传递将它们联系在一起
JMS 为消息服务定义了通用 Java 语言接口。它支持最常见的消息传递模型(包括发布/订阅和点到点)。
首先将平台无关的数据与 Java 技术放在一段文字中提及看起来比较奇怪。然而,既然JMS是一种基于 Java(因此是平台无关的)的技术,我们为什么在使用 JMS 时需要平台无关的数据呢?
答案来源于经常使用消息传递的环境。消息传递的一个最大优点体现在应用集成领域。被集成的应用多半不全是 Java 应用。
在这种情况下 JMS 非常理想,因为它是一种接口规范 -- 而不是实现。这意味着JMS位于已经有了相当的应用现有技术的上面一层。(当然,所有 Java 实现也能利用这种 JMS 和 XML 的解决方案。)
图 1. 位于专有消息服务上层的 JMS
图 1 说明了这样一种环境。非 Java 应用与专用消息服务直接进行通信。Java 应用通过 JMS 通信。每一样是无缝的,对吗?
但不完全是。数据仍然是一个需要解决的问题。
平台无关的数据解决了问题
请考虑 JMS 的五种消息类型。JMS 提供了三种结构化或半结构化的消息类型(MapMessage、ObjectMessage 和 StreamMessage)以及两种非结构化的或自由格式的消息类型(TextMessage 和 BytesMessage)。
结构化的消息格式只代表了众多处理结构化数据方法中的少数几种(只有映射表、序列化对象和数据元素流是直接表示的)。更重要的是,它们引发了与非 Java 应用交互操作的问题。转换或映射,特别是在转换涉及到序列化的类时是如何实现的呢?
非结构化的消息格式似乎能够更好地进行交互操作,但这仅仅是因为它们在消息上很少利用结构。然而这个很小的便利却为每个接受者加重了语法分析和确认的负担。
XML 减轻了这种负担。它为丰富的功能性数据结构提供了清晰的标准化途径,并通过越来越多的工具来支撑它,这些工具是用来执行语法分析和确认这些费力的工作的。
通过在环节中使用 XML,每一样都是无缝的。
代码
以下两段代码说明了如何传送 XML 消息。因为 XML 基本上是文本,所以它在 TextMessage 实例的主体中传送。两个示例都假设有 XMLValidator 类存在。这个类是许多基于 Java 的 XML 语法分析和确认工具之一的一个简单封装。
发送方是非常简单的。清单 1 中的代码说明了如何找到 Queue 和 QueueConnectionFactory、如何创建连接和会话、如何将 XML 填充到 TextMessage,以及如何将消息发送给队列。
清单 1. 发送 XML 消息的示例
public
static
void
send(
String stringQueue,
String stringQueueConnectionFactory,
XMLValidator xmlvalidator,
String stringXML)
throws
NamingException,
JMSException,
XMLValidationException {
//在一个名为JNDI和目录服务中查找Queue 和 QueueConnection 类厂,或者直接创建它们
Context context = new InitialContext();
Queue queue = null;
queue = (Queue)context.lookup(stringQueue);
QueueConnectionFactory queueconnectionfactory = null;
queueconnectionfactory =
(QueueConnectionFactory)context.lookup(stringQueueConnectionFactory);
QueueConnection queueconnection = null;
queueconnection = queueconnectionfactory.createQueueConnection();
QueueSession queuesession = null;
queuesession =
queueconnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建 QueueSender.
QueueSender queuesender = null;
queuesender = queuesession.createSender(queue);
//首先在XML中创建一个TextMessage,如果XML是通过用户输入创建的,那么验证XML的合法性是非常必要的。然后发送它。
xmlvalidator.validate(stringXML);
TextMessage textmessage;
textmessage = queuesession.createTextMessage();
textmessage.setText(stringXML);
queuesender.send(textmessage);
}
在接收方有许多事要做(见清单 2)。接收了 TextMessage 后,代码抽取 XML 并验证它。确认过程根据文档类型定义 (DTD) 来检查 XML,DTD 可以是 XML 的一部分,也可以在它的外部。
如果 DTD 是在外部存储的,您很可能要面临创建和维护企业范围的 DTD 资源库。资源库严格定义了共同参加的企业应用程序可以交换的消息的结构。
现在,TextMessage 成为非常有条理、定义明确的消息的“载体”,Java 和非 Java 应用程序都可以理解。
清单 2. 接收 XML 消息的示例
public
static
String
receive(
String stringQueue,
String stringQueueConnectionFactory,
XMLValidator xmlvalidator)
throws
NamingException,
JMSException,
XMLValidationException {
//在一个名为JNDI和目录服务中查找Queue 和 QueueConnection 类厂,或者直接创建它们
Context context = new InitialContext();
Queue queue = null;
queue = (Queue)context.lookup(stringQueue);
QueueConnectionFactory queueconnectionfactory = null;
queueconnectionfactory =
(QueueConnectionFactory)context.lookup(stringQueueConnectionFactory);
QueueConnection queueconnection = null;
queueconnection = queueconnectionfactory.createQueueConnection();
QueueSession queuesession = null;
queuesession =
queueconnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
// 创建 QueueReceiver.
QueueReceiver queuereceiver = null;
queuereceiver = queuesession.createReceiver(queue);
//接受一个TextMessage, 提取其中的XML,
//并在返回之前验证它。在验证XML和返回之前,将XML转换成一个DOM数或者其它的表示方法也是可以的。
TextMessage textmessage;
textmessage = (TextMessage)queuereceiver.receive();
String stringXML = textmessage.getText();
xmlvalidator.validate(stringXML);
return stringXML;
}
结束语
似乎大家有了共识,认为面向消息的中间件(JMS 是其一部分)和 XML 属于一起的。我希望我的论述为这个提法增添了说服力。它并不是那么出人意外的。XML 文档是真实的消息 -- 它们是结构化的,但仍具有相当的灵活性。另外,MOM,和 XML 一样,擅长集成异构应用程序。
学电脑知识 尽在www.zzzyk.com 电脑知识网