Java JMSCode使用数据库逐个发送和接收消息

Java JMSCode使用数据库逐个发送和接收消息,java,jms,ibm-mq,Java,Jms,Ibm Mq,在我访问了多个站点并学习了JMS之后,我编写了一个JMS独立客户端,从数据库中读取消息并逐个发送。我还想一条接一条地接收消息,然后更新数据库。 我需要使用标准JMS向队列和其他应用程序发送消息,该JMS将使用TextMessage,其正文将被读取为ISO-8859-1字符串。同样,他们也会以文本消息的形式发送回复。 我为循环编写了一个,从数据库中逐个读取消息 我是JMS新手,请您纠正我下面的代码是否能够正确地读取和发送消息到队列,以及接收和更新数据库。JMS类型中是否有任何需要更改的内容或需要更

在我访问了多个站点并学习了JMS之后,我编写了一个JMS独立客户端,从数据库中读取消息并逐个发送。我还想一条接一条地接收消息,然后更新数据库。 我需要使用标准JMS向队列和其他应用程序发送消息,该JMS将使用
TextMessage
,其正文将被读取为ISO-8859-1字符串。同样,他们也会以
文本消息
的形式发送回复。 我为循环编写了一个
,从数据库中逐个读取消息

我是JMS新手,请您纠正我下面的代码是否能够正确地读取和发送消息到队列,以及接收和更新数据库。JMS类型中是否有任何需要更改的内容或需要更正的内容。
for
循环工作正常吗

/*MQ Configuration*/
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(url);
mqQueueConnectionFactory.setChannel(channel);//communications link
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setQueueManager(qmgr);//service provider 
mqQueueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);

/*Create Connection */
QueueConnection queueConnection = mqQueueConnectionFactory.createQueueConnection();
queueConnection.start();

/*Create session */
QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

/*Create response queue */
//   Queue queue = queueSession.createQueue("QUEUE.RESPONSE");

int messageCount = 0;

Queue queue = queueSession.createQueue(replytoQueueName);
QueueSender queueSender = null;
QueueReceiver queueReceiver=null;

for (Testbean testBean : testbeanList) {
    String testMessage = testBean.getMessage();                 
    /*Create text message */
    textMessage = queueSession.createTextMessage(testMessage);

    logger.info("Text messages sent: " + messageCount);

    textMessage.setJMSReplyTo(queue);
    textMessage.setJMSType("mcd://xmlns");//message type
    textMessage.setJMSExpiration(2*1000);//message expiration
    textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT); //message delivery mode either persistent or non-persistemnt

    /*Create sender queue */
    //  QueueSender queueSender = queueSession.createSender(queueSession.createQueue("QUEUE.REQEST"));

    queueSender = queueSession.createSender(queueSession.createQueue(outputQName));
    queueSender.setTimeToLive(2*1000);
    queueSender.send(textMessage);

    /*After sending a message we get message id */
    System.out.println("after sending a message we get message id "+ textMessage.getJMSMessageID());
    String jmsCorrelationID = " JMSCorrelationID = '" + textMessage.getJMSMessageID() + "'";


    /*Within the session we have to create queue reciver */
    queueReceiver = queueSession.createReceiver(queue,jmsCorrelationID);

    /*Receive the message from*/
    Message message = queueReceiver.receive(60*1000);
    //   String responseMsg = ((TextMessage) message).getText();

    byte[] by = ((TextMessage) message).getText().getBytes("ISO-8859-1");

    logger.info(new String(by));
    String responseMsg = new String(by,"UTF-8");

    testDAO rmdao = new testDAO();
    rmdao.updateTest(responseMsg, jmsCorrelationID);        

    messageCount += 1;
}

queueSender.close();
queueReceiver.close();
queueSession.close();
queueConnection.close();
两件事:

  • 我将创建您的
    QueueSender
    Queue
    对象,将消息发送到
    for
    循环之外,因为它们似乎没有改变
  • 如果没有相应的使用者代码,根本无法判断选择器是否工作,但如果不对您发送的消息调用
    setCorrelationID()
    ,我会觉得有点奇怪。使用提供者分配的消息ID可能是IBM MQ请求/应答应用程序的常见模式,但使用关联ID的一般模式是对发送的消息调用
    setJMSCorrelationID()
    。这使代码更加清晰,还允许应用程序直接控制关联ID的唯一性。这对于应用程序的可移植性可能很重要(例如,如果您从IBM MQ迁移到其他JMS提供程序)因为不同的JMS提供者使用特定于其特定实现的消息ID的样式/格式。另外,关于消息ID,JMS规范声明,“唯一性的确切范围是由提供者定义的”,在我看来,这并不能很好地保证唯一性,特别是在使用
    java.util.UUID.randomUUID()之类的东西时。toString()
    非常简单
  • 您应该确保对JMS和数据库工作都使用XA事务,以便它们是原子的
  • finally
    块中关闭JMS资源
    • 两件事:

      • 我将创建您的
        QueueSender
        Queue
        对象,将消息发送到
        for
        循环之外,因为它们似乎没有改变
      • 如果没有相应的使用者代码,根本无法判断选择器是否工作,但如果不对您发送的消息调用
        setCorrelationID()
        ,我会觉得有点奇怪。使用提供者分配的消息ID可能是IBM MQ请求/应答应用程序的常见模式,但使用关联ID的一般模式是对发送的消息调用
        setJMSCorrelationID()
        。这使代码更加清晰,还允许应用程序直接控制关联ID的唯一性。这对于应用程序的可移植性可能很重要(例如,如果您从IBM MQ迁移到其他JMS提供程序)因为不同的JMS提供者使用特定于其特定实现的消息ID的样式/格式。另外,关于消息ID,JMS规范声明,“唯一性的确切范围是由提供者定义的”,在我看来,这并不能很好地保证唯一性,特别是在使用
        java.util.UUID.randomUUID()之类的东西时。toString()
        非常简单
      • 您应该确保对JMS和数据库工作都使用XA事务,以便它们是原子的
      • finally
        块中关闭JMS资源

      @Maxtech是根据回复中的correlationID设置为原始请求消息的messageID获取的。这是IBM MQ请求/回复应用程序的常见模式。感谢您更新您的答案。为了澄清IBM MQ保证,如果您让它生成messageID,则messageID将是唯一的,类似于您引用的UUID。您声明JMS规范声明“唯一性由提供者定义”,在本例中,提供者是IBM MQ。IBM MQ在知识中心记录了这一点。我对另一个问题“”有一个答案,我刚刚更新了一个指向IBM MQ生成的messageID唯一性的IBM文档的链接。正如我提到的,常见的IBM reply程序模式是将入站messageID复制到出站correlationID,但这并不是唯一的模式,另一种模式是将入站correlationID复制到出站correlationID。了解应用程序需要做什么的唯一方法是了解应答应用程序正在做什么。感谢您澄清IBM MQ提供的消息ID唯一性保证。然而,其他JMS提供者可能不会做出同样的保证,这就是我在回答中提到应用程序可移植性的原因。通常最好不要依赖于特定于供应商的担保,因为这可能导致供应商锁定。JMS规范本身不提供特定的消息ID唯一性保证,因此我认为JMS应用程序不应该依赖它,而是应该确保其应用程序做出自己的保证。@Maxtech是基于回复中的correlationID设置为原始请求消息的messageID来获取的。这是IBM MQ请求/回复应用程序的常见模式。感谢您更新您的答案。为了澄清IBM MQ保证,如果您让它生成messageID,则messageID将是唯一的,类似于您引用的UUID。您声明JMS规范声明“唯一性由提供者定义”,在本例中,提供者是IBM MQ。IBM MQ在知识中心记录了这一点。我对另一个问题“”有一个答案,我刚刚更新了一个指向IBM MQ生成的messageID唯一性的IBM文档的链接