开发企业应用程序以使用 JMS
使用此任务来开发企业应用程序直接使用 JMS API 以进行异步消息传递。
关于此任务
此主题概述了开发需要直接使用 JMS API 来进行异步消息传递的企业应用程序(servlet 或企业 Bean)所需的步骤。
本主题仅描述与 JMS 相关的事宜;不描述您应该已熟悉的一般企业应用程序编程。有关这些步骤的详细信息,以及获取开发企业应用程序以使用 JMS 的示例,请参阅 Java™ 消息服务文档
WebSphere® Application Server 管理支持会对 WebSphere Application Server 定义企业应用程序所使用的 JMS 资源的详细信息,并将这些信息绑定至 JNDI 名称空间。
要使用 JMS,请完成以下一般步骤:
过程
- 导入 JMS 软件包。 使用 JMS 的企业应用程序以 JMS 的多个导入语句开头,这些导入语句至少应包括:
import javax.jms.*; //JMS interfaces import javax.naming.*; //Used for JNDI lookup of administered objects
- 获取初始上下文:
try { ctx = new InitialContext(env); ...
- 从 JNDI 名称空间检索受管对象。 InitialContext.lookup() 方法用于检索受管对象(JMS 连接工厂和 JMS 目标)。以下示例显示如何接收来自队列的消息:
qcf = (QueueConnectionFactory)ctx.lookup( qcfName ); ... inQueue = (Queue)ctx.lookup( qnameIn ); ...
还可使用另一种方法来通过 JNDI 查询获取管理定义的 JMS 目标对象,那就是使用 Session.createQueue(String) 方法或 Session.createTopic(String) 方法,但这种方法不易管理。例如:
创建一个可用来引用现有目标 Q1 的 JMS 队列实例。Queue q = mySession.createQueue("Q1");
这些 create 方法最简单格式的参数就是现有目标的名称。对于更复杂的情况,应用程序可以使用基于 URI 的格式,它允许提供任意数量的名称值对,以设置 JMS 目标对象的各种属性。
- 创建到消息传递服务提供者的连接。 此连接提供对底层传输的访问,并用于创建会话。工厂对象上的 createQueueConnection() 方法用于创建连接。
connection = qcf.createQueueConnection();
JMS 规范定义连接应该在停止状态下创建。在连接启动前,与该连接相关联的 MessageConsumers 不能接收任何消息。要启动连接,请发出以下命令:connection.start();
- 创建用于发送或接收消息的会话。 会话提供用于生产和消费消息的上下文,包含用于创建 MessageProducers 和 MessageConsumers 的方法。
createQueueSession 方法用于在连接上获取会话。
方法具有两个参数:
- 用于确定会话是不是事务性的布尔值。
- 用于确定应答方式的参数。
boolean transacted = false; session = connection.createQueueSession( transacted, Session.AUTO_ACKNOWLEDGE);
在此示例中,会话不是事务的,它应该自动应答接收到的消息。使用这些设置,仅在系统出错,或应用程序意外终止后,回退消息。
下列各点(如 EJB 规范中所定义)应用到这些标志:- 全局事务中忽略在 createQueueSession 上传递的事务标志,所有工作作为事务的一部分执行。在事务外使用事务标志,而且如果事务标志设置为 true,那么应用程序应该使用 session.commit() 和 session.rollback() 来控制工作的完成。在 EJB2.0 模块中,如果事务标志设置为 true 并位于 XA 事务外部,那么会话包含在 WebSphere 局部事务中,并且该方法的未解析操作属性将应用于 JMS 工作(如果应用程序未落实或回滚该属性)。
- 客户机不能使用 Message.acknowledge() 来应答消息。如果 CLIENT_ACKNOWLEDGE 的值在 createxxxSession 调用上传递,那么消息由应用程序服务器自动确认,而不使用 Message.acknowledge()。
- 发送消息。
- 创建 MessageProducers 以创建消息。 对于点到点消息传递,MessageProducer 是通过将输出队列对象(先前检索到的)传递给会话上 createSender 方法而创建的 QueueSender。通常对特定队列创建 QueueSender,以便将该发送方所发送的所有消息都发送到同一目标。
QueueSender queueSender = session.createSender(inQueue);
- 创建消息。 使用会话创建空消息,并添加传递的数据。
JMS 提供多种消息类型,每种类型体现其内容的一些知识。要避免引用消息类型的供应商特定类名称,在 Session 对象上为消息创建提供方法。
在以下示例中,根据 outString 属性创建文本消息:TextMessage outMessage = session.createTextMessage(outString);
- 发送消息。 要发送消息,将消息传递到 QueueSender 上的发送方法:
queueSender.send(outMessage);
- 创建 MessageProducers 以创建消息。 对于点到点消息传递,MessageProducer 是通过将输出队列对象(先前检索到的)传递给会话上 createSender 方法而创建的 QueueSender。通常对特定队列创建 QueueSender,以便将该发送方所发送的所有消息都发送到同一目标。
- 接收应答。
- 创建一个相关标识以将发送的消息与任何应答链接到一起。 在此示例中,客户机使用 JMSCorrelationID 中提供程序特定消息标识,接收与其发送的消息相关的应答消息。
messageID = outMessage.getJMSMessageID();
然后,相关标识用于消息选择器,以仅选择具有此标识的消息:String selector = "JMSCorrelationID = '"+messageID+"'";
- 创建 MessageReceiver 以接收消息。 对于点到点,MessageReceiver 是通过将输入队列对象(先前检索到的)和消息选择器传递到会话上 createReceiver 方法中而创建的 QueueReceiver。
QueueReceiver queueReceiver = session.createReceiver(outQueue, selector);
- 检索应答消息。 要检索应答消息,使用 QueueReceiver 上的接收方法:
Message inMessage = queueReceiver.receive(2000);
接收调用中的参数是超时,以毫秒为单位。此参数定义如果没有消息立即可用时,方法等待多久。 如果您省略此参数,那么调用将被无限期地阻塞。如果您不要任何延迟,那么使用 receiveNoWait() 方法。在此示例中,当消息到达时,或 2000ms 后(哪个早选哪个),接收调用返回。
- 在接收消息上操作。 当接收消息时,您可按客户机业务逻辑的需要对它操作。一些一般 JMS 操作检查消息的类型是否正确,并抽取消息的内容。要从消息主体抽取内容,您需要将通用 Message 类(声明的接收方法返回类型)强制类型转换为更具体的子类,如 TextMessage。好的实践是总在数据类型转换前测试消息类,以便适度处理意外错误。
在此示例中,instanceof 运算符用于检查接收的消息类型为 TextMessage。然后,通过将消息内容数据类型转换为 TextMessage 子类,以进行抽取。
if ( inMessage instanceof TextMessage ) ... String replyString = ((TextMessage) inMessage).getText();
- 创建一个相关标识以将发送的消息与任何应答链接到一起。 在此示例中,客户机使用 JMSCorrelationID 中提供程序特定消息标识,接收与其发送的消息相关的应答消息。
- 关闭。 如果应用程序需要在会话层或更低层创建很多短期活动的 JMS 对象,那么关闭所有已使用的 JMS 资源很重要。
要这样做,在资源不再需要时,在各种类(QueueConnection、QueueSession、QueueSender 和 QueueReceiver)上调用 close() 方法。
queueReceiver.close(); ... queueSender.close(); ... session.close(); session = null; ... connection.close(); connection = null;
- 发布并预订消息。 要使用 JMS 发布/预订支持,而不是点到点消息传递,一般操作是相同的;例如,创建会话和连接。
例外是使用本主题资源,而不是使用队列资源(如 TopicPublisher 而不是 QueueSender)来发布消息,如以下示例中所示:
// Creating a TopicPublisher TopicPublisher pub = session.createPublisher(topic); ... pub.publish(outMessage); ... // Closing TopicPublisher pub.close();
- 处理错误 任何 JMS 运行时错误由异常报告。JMS 中的多数方法抛出 JMSExceptions 以表明错误。好的编程实践是捕获这些异常,并将它们显示在合适的输出上。
与一般 Java 异常不同,JMSException 可以包含嵌入式异常。JMSException 实现在它的 toString() 方法的输出中不包含嵌入式异常。因此,您必须显式检查嵌入式异常并将它输出,如以下示例中所示:
catch (JMSException je) { System.out.println("JMS failed with "+je); Exception le = je.getLinkedException(); if (le != null) { System.out.println("linked exception "+le); } }
下一步做什么


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tmj_devap
文件名:tmj_devap.html