开发 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 资源。

过程

  1. 导入 JMS 软件包。 使用 JMS 的企业应用程序启动时有很多 JMS import 语句;例如:
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.rmi.PortableRemoteObject;
    import javax.jms.*;
  2. 获取初始上下文。
       try     {
            ctx = new InitialContext(env);
    ...
  3. 定义客户机即将使用的参数;例如,识别队列连接工厂和组装要发送的消息。
    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;
    
    ...
  4. 从 JNDI 名称空间检索受管对象。 InitialContext.lookup() 方法用于检索受管对象(队列连接工厂和队列目标):
           qcf = (QueueConnectionFactory)ctx.lookup( qcfName );
    ...
           inQueue = (Queue)ctx.lookup( qnameIn );
           outQueue = (Queue)ctx.lookup( qnameOut );
    ...
  5. 创建到消息传递服务提供者的连接。 此连接提供对底层传输的访问,并用于创建会话。工厂对象上的 createQueueConnection() 方法用于创建连接。
           connection = qcf.createQueueConnection();
    JMS 规范定义连接应该在停止状态下创建。在连接启动前,与该连接相关联的 MessageConsumers 不能接收任何消息。要启动连接,请发出以下命令:
           connection.start();
  6. 创建会话,用于发送和接收消息。 会话提供用于生产和消费消息的上下文,包含用于创建 MessageProducers 和 MessageConsumers 的方法。 createQueueSession 方法用于在连接上获取会话。 方法具有两个参数:
    • 用于确定会话是不是事务性的布尔值。
    • 用于确定应答方式的参数。
           boolean transacted = false;
           session = connection.createQueueSession( transacted,
                                                   Session.AUTO_ACKNOWLEDGE);

    在此示例中,会话不是事务的,它应该自动应答接收到的消息。使用这些设置,仅在系统出错,或客户机应用程序意外终止后,回退消息。

  7. 发送消息。
    1. 创建 MessageProducers 以创建消息。 对于点到点,MessageProducer 是通过将输出队列对象(先前检索到的)传递给会话上 createSender 方法而创建的 QueueSender。通常对特定队列创建 QueueSender,以便将该发送方所发送的所有消息都发送到同一目标。
             QueueSender queueSender = session.createSender(inQueue);
    2. 创建消息。 使用会话创建空消息,并添加传递的数据。

      JMS 提供多种消息类型,每种类型体现其内容的一些知识。要避免引用消息类型的供应商特定类名称,在 Session 对象上为消息创建提供方法。

      在此示例中,从 outString 属性创建文本消息,此属性可以是作为客户机程序调用上的输入参数提供的,或由其他一些方法构造的:
             TextMessage outMessage = session.createTextMessage(outString);
    3. 发送消息。
      要发送消息,将消息传递到 QueueSender 上的发送方法:
             queueSender.send(outMessage);
  8. 接收应答。
    1. 创建一个相关标识以将发送的消息与任何应答链接到一起。 在此示例中,客户机使用 JMSCorrelationID 中提供程序特定消息标识,接收与其发送的消息相关的应答消息。
             messageID = outMessage.getJMSMessageID();
      然后,相关标识用于消息选择器,以仅选择具有此标识的消息:
             String selector = "JMSCorrelationID = '"+messageID+"'";
    2. 创建 MessageReceiver 以接收消息。 对于点到点,MessageReceiver 是通过将输入队列对象(先前检索到的)和消息选择器传递到会话上 createReceiver 方法中而创建的 QueueReceiver。
             QueueReceiver queueReceiver = session.createReceiver(outQueue, selector);
    3. 检索应答消息。 要检索应答消息,使用 QueueReceiver 上的接收方法:
             Message inMessage = queueReceiver.receive(2000);

      接收调用中的参数是超时,以毫秒为单位。此参数定义如果没有消息立即可用时,方法等待多久。 如果您省略此参数,那么调用将被无限期地阻塞。如果您不要任何延迟,那么使用 receiveNoWait() 方法。在此示例中,当消息到达时,或 2000ms 后(哪个早选哪个),接收调用返回。

    4. 在接收消息上操作。 当接收消息时,您可按客户机业务逻辑的需要对它操作。一些一般 JMS 操作检查消息的类型是否正确,并抽取消息的内容。要从消息主体抽取内容,请从通用 Message 类(这是接收方法的已声明返回类型)强制转换为更具体的子类(如 TextMessage)。好的实践是总在数据类型转换前测试消息类,以便适度处理意外错误。

      在此示例中,instanceof 运算符用于检查接收的消息类型为 TextMessage。然后,通过将消息内容数据类型转换为 TextMessage 子类,以进行抽取。

             if ( inMessage instanceof TextMessage )
      
      ...
                 String replyString = ((TextMessage) inMessage).getText();
  9. 关闭。 如果应用程序需要在会话层或更低层创建很多短期活动的 JMS 对象,那么关闭所有已使用的 JMS 资源很重要。 要这样做,在资源不再需要时,在各种类(QueueConnection、QueueSession、QueueSender 和 QueueReceiver)上调用 close() 方法。
           queueReceiver.close();
    ...
           queueSender.close();
    ...
           session.close();
           session = null;
    ...
           connection.close();
           connection = null;
  10. 发布和预订消息。 要使用发布/预订支持,而不是点到点消息传递,一般客户机操作是相同的;例如,创建会话和连接。 例外是使用本主题资源,而不是使用队列资源(如 TopicPublisher 而不是 QueueSender)来发布消息,如以下示例中所示:
    // Creating a TopicPublisher
           TopicPublisher pub = session.createPublisher(topic);
    ...
           pub.publish(outMessage);
    ...
           // Closing TopicPublisher
           pub.close();
  11. 处理错误 任何 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 客户机应用程序


指示主题类型的图标 任务主题



时间戳记图标 最近一次更新时间: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tmj_devcl
文件名:tmj_devcl.html