清单 8. ShopStorage 代码片段
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination",
propertyValue = "OrderTopic")
})
public class ShopStorage implements MessageListener {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("ShopStorage: Order Received \n" + textMessage.getText());
//find good in storage
......
} catch (JMSException e) {
e.printStackTrace();
}
}
} |
从代码中可见,MDB 继承了 java.jms.MessageListeneron 接口,并在 onMessage() 方法中接收并处理消息。当有消息到达时,MDB 的 onMessage() 方法会被自动执行,参数 message 就是所接收到的消息。通过 @MessageDriven 及 @ActivationConfigProperty 对 JMS 资源引用,指定了该 MDB 可以接收的消息来源。ShopAccountant 与 ShopStorage 都只接收 OrderTopic 中传递的消息。
点对点消息
发送消息
示例中,仓库完成提货后需要通知运输部门。因此,需要在 ShopStorage 中添加相应代码,以完成发送消息的动作。
以下是 ShopStorage 中添加的代码:
清单 9. ShopStorage.java
public class ShopStorage implements MessageListener {
@Resource(name = "OrderConnectionFactory")
private ConnectionFactory factory;
@Resource(name = "OrderQueue")
private Queue orderQueue;
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
......
Connection connection;
connection = factory.createConnection();
Session sess = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
TextMessage msg = sess.createTextMessage();
msg.setStringProperty("CustomerId", customerId);
msg.setStringProperty("GoodsId", goodsId);
MessageProducer messageProducer = sess.createProducer(orderQueue);
messageProducer.send(msg);
System.out.println("ShopStorage: get ready to deliver goods.");
} catch (JMSException e) {
e.printStackTrace();
}
}
} |
上述代码与 OrderSenderBean 中发送消息的代码十分相似。不同点在于这里使用了 JMS 的消息队列 (Queue) 资源 -OrderQueue,而 OrderSenderBean 则使用了 JMS 的主题 (Topic) 资源。
接收消息
创建 ShopTransporter 类表示运输部门。与之前接收消息的方式相似,ShopTransporter 也是一个消息驱动组件 (MDB)。可见,MDB 可以方便的使用于接收任何一种 JMS 消息模型。
清单 10. ShopTransporter 的代码
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName =
"destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName =
"destination", propertyValue = "OrderQueue"),})
public class ShopTransporter implements MessageListener {
public void onMessage(Message message) {
......
}
} |
此段代码与之前的 MDB 非常相似,同样使用了 @ActivationConfigProperty 与 @MessageDriven 来绑定 JMS 资源。不同点在于,ShopTransporter 使用了消息队列 (Queue) 而不再是主题 (Topic), 表示 ShopTransporter 直接收 OrderQueue 中传递的消息。
运行
与前一篇文章相同,运行应用程序前,需要将 ShopEAR 部署至应用服务器上。登录后,用户可以点击“buy”链接,购买商品。上述代码中的输出信息将显示在应用服务器的终端中。
应用程序的输出信息如图 3 所示:
图 3. 运行结果
总结
本文以 WAS CE v2.1 为平台,通过一个示例向您阐述了 JMS 应用的基本开发过程,包括 JMS 资源及 Resouces Adapter 的创建、两类 JMS 消息 ( 通过 Queue 及 Topic) 的发送、JMS 消息的接收。无论采用何种消息模型,利用 WAS CE 2.1 开发 JMS 应用的基本流程可以归纳如下:
定义 JMS 资源
•创建 JMS 资源定义文件,定义所需要的 JMS 资源
•加入 ActiveMQ 资源适配器,作为应用程序的一个模块
发送消息
•利用 ConnectionFactory 创建 Connection,连接至 JMS Provider
•利用 Connection 创建 Session
•利用 Session 创建发送者及消息
•发送者发送消息
接收消息
•创建 MDB,实现 java.jms.MessageListener 接口
•实现 onMessage() 方法,接收并处理消息
WAS CE v2.1 为各种 Java EE 技术提供了强大的支持。通过 ActiveMQ 作为 JMS Provider,开发人员可以在 WAS CE 上便捷地开发出各种复杂应用。