开发 JMS 客户机
使用此任务开发 JMS 客户机应用程序,以使用消息与企业应用程序进行通信。
关于此任务
本主题提供开发 JMS 客户机应用程序时需要执行的步骤的概述。本主题仅描述与 JMS 相关的案例;它不描述您应该已熟悉的一般客户机编程。有关这些步骤的详细信息和开发 JMS 客户机的示例,请参阅 Java™ 消息服务文档和 IBM MQ 信息中心的“使用 Java”一节。
JMS 客户机假设 JMS 资源(如队列连接工厂和队列目标)已存在。客户机应用程序可以通过 JNDI 查询或以程序性方式获取适合的 JMS 资源,而不需要使用 JNDI。
有关带有 WebSphere® Application Server 的 JMS 瘦客户机(该瘦客户机是一种可嵌入式技术,用于提供与 WebSphere Application Server 缺省消息传递提供程序消息传递引擎的连接)的信息,请参阅 使用 JMS 连接至 WebSphere Application Server 缺省消息传递提供程序消息传递引擎。
有关开发客户机应用程序和为它们配置 JMS 资源的更多信息,请参阅开发 J2EE Application Client 代码和相关任务。
要使用 JMS,典型的 JMS 客户机程序应该完成以下一般步骤。此示例说明的是使用 JNDI 查询来获取 JMS 资源。
过程
- 导入 JMS 软件包。 使用 JMS 的企业应用程序启动时有很多 JMS import 语句;例如:
import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import javax.jms.*;
- 获取初始上下文。
try { ctx = new InitialContext(env); ...
- 定义客户机即将使用的参数;例如,识别队列连接工厂和组装要发送的消息。
public class JMSppSampleClient { public static void main(String[] args) throws JMSException, Exception { String messageID = null; String outString = null; String qcfName = "java:comp/env/jms/ConnectionFactory"; String qnameIn = "java:comp/env/jms/Q1"; String qnameOut = "java:comp/env/jms/Q2"; boolean verbose = false; QueueSession session = null; QueueConnection connection = null; Context ctx = null; QueueConnectionFactory qcf = null; Queue inQueue = null; Queue outQueue = null; ...
- 从 JNDI 名称空间检索受管对象。 InitialContext.lookup() 方法用于检索受管对象(队列连接工厂和队列目标):
qcf = (QueueConnectionFactory)ctx.lookup( qcfName ); ... inQueue = (Queue)ctx.lookup( qnameIn ); outQueue = (Queue)ctx.lookup( qnameOut ); ...
- 创建到消息传递服务提供者的连接。 此连接提供对底层传输的访问,并用于创建会话。工厂对象上的 createQueueConnection() 方法用于创建连接。
connection = qcf.createQueueConnection();
JMS 规范定义连接应该在停止状态下创建。在连接启动前,与该连接相关联的 MessageConsumers 不能接收任何消息。要启动连接,请发出以下命令:connection.start();
- 创建会话,用于发送和接收消息。 会话提供用于生产和消费消息的上下文,包含用于创建 MessageProducers 和 MessageConsumers 的方法。
createQueueSession 方法用于在连接上获取会话。
方法具有两个参数:
- 用于确定会话是不是事务性的布尔值。
- 用于确定应答方式的参数。
boolean transacted = false; session = connection.createQueueSession( transacted, Session.AUTO_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;
- 发布和预订消息。 要使用发布/预订支持,而不是点到点消息传递,一般客户机操作是相同的;例如,创建会话和连接。
例外是使用本主题资源,而不是使用队列资源(如 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); } }
下一步做什么
有关针对特定远程服务器运行客户机的信息,请参阅使用 launchClient 来运行 Java EE 客户机应用程序。


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