级别: 初级 Rachel Reinitz (rreinitz@us.ibm.com), 高级 IT 咨询专家, IBM Andre Tost, 高级技术人员, IBM
2005 年 5 月 01 日 这是本系列文章的第三部分,描述了在 IBM® WebSphere® Application Server V6 中的新的消息传递引擎来构建企业服务总线(Enterprise Service Bus,ESB),我们将设置消息驱动 bean 来监听 JMS 队列的消息并设置 J2EE 客户端应用程序来向那个 JMS 队列发送消息。我们还会看一下在应用程序服务器上通过消息总线发送 JMS 消息所必需的设置。
引言
现在我们已经浏览了在 IBM WebSphere Application Server V6 中支持的消息传递资源的基础(在第 1 部分中),描述了我们将在本系列文章中使用的业务场景(Posts-R-Us 公司),并看到了如何创建消息传递总线的实例(在第 2 部分中),现在到了该做些实际工作的时候了!
在第 3 部分中,我们将向您展示如何创建一个简单的点对点的基于 JMS 的消息传递的应用程序。这个应用程序由一个发送部分(在 J2EE™ 客户端应用程序内运行),和一个接收部分(以消息驱动 bean 为代表)组成。在创建此应用程序的过程中,我们将看到在应用程序服务器中通过消息总线发送 JMS 消息所必需的设置。
JMS 和总线
在接下来的业务场景中,我们将假定无论包何时被传递给消费者,消息都必须发送给 Posts-R-Us 的主系统以便确认此传递。该确认消息异步传送,也就是,没有需要的响应,此消息简单地排列到主系统中用于处理。
可能您现在认为,在 MDB 中发送消息给 JMS 队列,并从那儿进行接收是非常令人兴奋或新鲜的。您是对的。然而,它之所以有趣是基于以下事实:消息通过消息传递总线正确发送到目的地。它可以使我们使用中介来应用可选的消息传递的处理,比如过滤消息内容或者路由到其它不同的目的地,仅仅是命名几个而已。换句话说,总线在将消息传递到消费者之前就对它进行了控制,也就是 MDB,提供了在传统的 JMS 场景中无法获得的控制级别。
在 WebSphere Application Server V6 中创建 JMS 资源
第一步,我们将在应用程序服务器中创建一些构件:JMS 连接工厂、JMS 队列(MDB 的激活规范)当然还有总线目的地。我们将从总线目的地开始,然后配置 JMS 资源:
- 打开 WebSphere Application Server 管理控制台(服务器必须保持运行)。
- 在左侧的导航面板中选择 Service Integration => Buses。
- 选择 TheBus,然后在下面的对话框中选择 Destinations。
- 当前定义的总线目的地清单展示出来,选择 New。
- 注意您可以创建几种类型的目的地。在我们的例子中,我们将使用 Queue 目的地。选择 Next。
- 进入
PackageReceivedDestination 标志符, 然后选择 Next。
- 再次点击 Next 接收总线成员,然后点击 Finish。
- 保存您所作的修改,然后在列表中可以看到新总线,如图 1 所示。
图 1. 总线目的地
- 现在准备创建 JMS 构件。在管理控制台的导航面板中,选择 Resources => JMS Providers => Default Messaging。我们将此作用范围定为 Node,为默认值。图 2 展示了此对话框。
图 2. 默认的消息传递提供者配置
- 创建连接工厂,选择 JMS Connection Factory 链接,然后选 New。在创建对话框中,进入下列各项(图 3):
- 名称:
TheConnectionFactory
- JNDI 名称:
jms/TheConncectionFactory
- 总线名称:
TheBus
保持其它的默认值,然后点击 OK 保存您所做的修改。
图 3. JMS 连接工厂
- 接下来,在默认的消息传递提供者窗口(图 2)中选择 JMS Queue 链接并点击 New。
- 进入下列各项(图 4):
- 名称:
PackageReceivedQueue
- JNDI 名称:
jms/PackageReceivedQueue
- 总线名称:
TheBus
- 队列名称:
PackageReceivedDestination
保持其它的默认值,然后点击 OK 保存您所做的修改。
图 4. JMS 队列
- 我们需做的最后一件事情是激活规范,它对于 J2EE 1.4 是新的,并且将 MDB 捆绑到队列中。在 MDB 的部署描述符中,您定义激活规范的 JNDI。对于激活规范本身,您确定 MDB 应该监听的队列。返回管理控制台的 Default Messaging Provider 窗口(图 2),选择 JMS activation specification,然后选择 New。
- 输入或选择下列值(图 5):
- 名称:
PackageReceivedActivationSpec
- JNDI 名称:
eis/PackageReceivedActivationSpec
- 目的地类型:queue
- 目的地 JNDI 名称:
jms/PackageReceivedQueue
- 总线名称:TheBus
保持其它的默认值,然后点击 OK 保存您所做的修改。
图 5. JMS 激活规范
这些是我们发送消息到总线和从那儿到消息驱动 bean 需要的所有构件。接下来我们将看一下实际的 Java 代码。
Java 代码
我们不会花费很多时间来描述即将用于本例的代码,因为它同其他任何规范的 JMS 代码真的没有区别(请参阅 JMS 的参考资料部分),而且您能在下载章节中下载我们所使用的代码,包括所需的 J2EE 部署描述符。
发送者主要将发送一个约束传递包的数量的文本消息。因为发送者代码在 J2EE 客户端应用程序中运行,所以我们无法对所用的 JMS 资源的名称进行硬编码。我们使用 java:comp/env namespace 来代替。这两个名称,一个用于连接工厂,一个用于实际队列,在客户端应用程序部署描述符中利用资源引用它们被束缚起来。
这里是客户端代码的摘录:
清单 1
public class Main {
private final static String JMSCF_JNDI_NAME = "java:comp/env/jms/TheConnectionFactory";
private final static String JMSQ_JNDI_NAME = "java:comp/env/jms/PackageReceivedQueue";
private final static String messageText = "Package Received - 24595023";
public static void main(String[] args) throws Exception {
InitialContext initCtx = new InitialContext();
// Finding the WAS QueueConnectionFactory
javax.jms.ConnectionFactory qcf = (javax.jms.ConnectionFactory) initCtx.lookup(JMSCF_JNDI_NAME);
// Finding the Queue Destination
Destination q = (Destination) initCtx.lookup(JMSQ_JNDI_NAME);
// Create JMS Connection
Connection connection = qcf.createConnection();
// Create JMS Session
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create MessageProducer and TextMessage
MessageProducer queueSender = session.createProducer(q);
TextMessage outMessage = session.createTextMessage();
outMessage.setText(messageText);
// Set type and destination and send
outMessage.setJMSType("package_received");
outMessage.setJMSDestination(q);
queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
queueSender.send(outMessage);
connection.close();
System.out.println("Send completed");
}
}
|
对于 MDB,事情变得更简单了。每一个 MDB 有一个称为 onMessage() 的方法。一旦消息到达 MDB 监听的队列时,这个方法就被调用了。在我们例子中它是这样的:
清单 2.
public void onMessage(javax.jms.Message msg) {
if (!(msg instanceof TextMessage)) {
System.out.println("Received message is not a text message!");
throw new RuntimeException();
}
TextMessage textMsg = (TextMessage)msg;
try {
System.out.println("Received message : "+textMsg.getText());
// forward the received message to business logic for processing...
} catch (JMSException x) {
throw new RuntimeException(x);
}
}
|
客户端应用程序和 MDB 两者都有部署描述符。在这里我们将快速浏览一遍。
客户端部署描述符,在一个称为 application-client.xml 的文件中,包含对用于上述代码中 JMS 连接工厂和队列中 JNDI 名称的引用。如果您在 Application Server Toolkit 中打开客户端部署描述符,它将看起来更加简单,如图 6 所示。
图 6. 客户端部署描述符
在代码中,用到的 Name 值与 java:comp/env 名称空间结合一起。它在代码中用作名为 JMSCF_JNDI_NAME 的变量。WebSphere Bindings 下的输入展示了当它在应用程序服务器被部署时的资源的实际名称(记住我们早先创建的名为 jms/TheConnectionFactory 的 JMS 连接工厂)。
MDB 的部署描述符包含对 JMS 激活规范(它与我们前面创建的 JMS 队列依次联合)的引用,如图 7 所示。
图 7. MDB 部署描述符
我们为该 MDB 定义称为 package_received 的消息选择器,它能更进一步地过滤进来的消息。消息选择器在 JMS 消息的客户端代码上设置:
outMessage.setJMSType("package_received");
我们将客户端和 MDB 模块打包到 EAR 文件中,分别命名为 PackageReceivedClient.ear 和 PackageReceived.ear。在我们运行客户端之前,必须将 MDB 安装并部署到应用程序服务器中。我们接下来就进行操作。
安装和运行 Java 代码
安装和部署 MDB:
- 在管理控制台,在左侧的导航面板选择 Applications => Enterprise Applications。
- 选择 Install。
- 选择 Local file system,进入包含 MDB 的 EAR 文件的名称和目录中,然后选择 Next。
- 确保 Generate Default Bindings 已经核查过并选择 Next。
- 在下面的窗口中,核查 Deploy enterprise beans,然后选择 Next。
- 在接下来的两个对话框中选择 Next,没有任何修改。
- 注意在下面的窗口中,您能重写激活规范的设定值,包括正被使用的 JMS 队列(图 8)。
图 8. 重写激活规范的性能
我们在此不必修改任何东西,但这里展示了在 EAR 文件和部署描述符中应用程序开发者如何调整其设置值。
- 选择 Next,然后是 Finish。当完成部署步骤时,保存您的修改。
- 您的控制台浏览器窗口将看起来如图 9 所示。
图 9. 安装应用程序后的管理控制台
注意新的应用程序已经安装,但并未被启动。要启动它,选择与应用程序相邻的检验栏,然后选择 Start。MDB 现在已经准备从总线接收消息。
- 运行程序客户端发送消息到总线,打开命令提示窗口,改到您正使用的应用程序服务器概要的 \bin 目录下。举个例子,如果您的概要命名为 MyShippingCo 并且您所安装的 WebSphere Application Server 在 c:\WebSphere\AppServer6 目录下,那么 c:\WebSphere\AppServer6\profiles\MyShippingCo\bin 将是您所需要的目录。
- 通过调用 setupcmdline 实用程序设置合适的环境。
- 现在,通过调用 launchclient 实用程序来开启客户端应用程序,传递客户端 EAR 文件作为参数,如图 10 所示。
图 10. 开启 launchclient 实用程序
- 在 \logs\server1 目录下检查 SystemOut.log 文件。这是 MDB 输出的地方,而且它将展示图 11 中打印的消息。
图 11. SystemOut.log 文件
输出的日志文件将包含有用的信息以防出现问题,因此检查它通常是一个很好的做法。
结束语
在本文中,我们描述了用 WebSphere Application Server V6 Messaging Resources 构建企业服务总线的通用场景。无论何时传递包,我们构建的服务器都会向总线发送确认消息,使用 JMS 作为与总线通信的协议。消息的接收者是消息驱动 bean,也使用 JMS 作为它的协议。
在以后的文章中,我们将向您展示当消息从总线中经过时,如何利用中介进行操作。因此请耐心等待。
下载 | 名字 | 大小 | 下载方法 |
|---|
| PackageReceived.ZIP | 8 KB |
FTP | HTTP |
参考资料
作者简介  | |  |
Rachel Reinitz 是 IBM Software Services for WebSphere 中重点研究 Web 服务的高级 IT 咨询专家。Rachel 咨询客户和独立软件商关于怎样才能将面向服务的体系结构及 Web 服务用于达到他们的业务以及技术目标。她进行了 IBM 高级 Web 服务培训教程的开发并且经常作为会议的主持人。Rachel 同时也是有过 4 年 XP 实践、经验丰富的极限编程专家。她居住在加利福尼亚州的 Bay 区,喜爱徒步旅行、社会活动、以及国际旅行。 |
 | |  |
Andre Tost 是 WebSphere Business Development 小组的一位高级技术人员,他在这个部门帮助 IBM 的战略联盟伙伴把他们的应用程序与 WebSphere 集成在一起。他的工作重点是贯穿整个 WebSphere 产品系列的 Web 服务技术。在开始从事他目前的工作之前,有十年的时间他在 IBM 软件开发工作中担任各种开发和体系结构方面的角色,最近他从事于 WebSphere Business Components 产品。他出生于德国,目前在美国明尼苏达州的罗切斯特居住和工作。在业余时间,他喜欢和他的家人在一起,只要有可能就去踢球或者看球。 |
对本文的评价
|