【问题标题】:Cannot delete JMS properties when sending message to queue将消息发送到队列时无法删除 JMS 属性
【发布时间】:2020-05-28 12:57:04
【问题描述】:

我正在使用 JMSTemplate 和 IBM 队列管理器发送一条简单的消息。

public void sendSomething(String message) throws JMSException {
    jmsTemplate.convertAndSend(""queue:///MYQUEUE?targetClient=1"","my message");
  }

我在jms模板库上调试,发现在最后一个负责发送消息的方法中:

protected void doSend(MessageProducer producer,
                      Message message)
               throws JMSException

...
producer.send(message);
...

message 有很多属性,例如 JMSMessage、JMSType、JMSDeliveryMode.... 和正文(我的消息)。

我怎样才能只发送正文并删除所有这些属性?

【问题讨论】:

    标签: ibm-mq spring-jms


    【解决方案1】:

    你不能;这就是 JMS 的工作原理;阅读规范。

    如果您谈论的是 IBM MQ RFH2 标头,并且使用者是本机 MQ 应用程序(不是 JMS),请参阅 here

    MQRFH2 是可选的,它包含在传出消息中由 JMS 目标类中的 TARGCLIENT 标志控制。您可以使用 IBM MQ JMS 管理工具设置此标志。因为 MQRFH2 携带特定于 JMS 的信息,所以当发送方知道接收目的地是 JMS 应用程序时,始终将其包含在消息中。通常,在将消息直接发送到非 JMS 应用程序时省略 MQRFH2。这是因为这样的应用程序不期望在其 IBM MQ 消息中包含 MQRFH2。

    我相信这意味着您必须发送到 Destination 对象而不是目标名称;目的地具有属性集:

    mqDestination.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
    

    【讨论】:

    • 好的。对于这种特殊情况,您有什么建议?
    • 不清楚您要达到的目标。如果您不关心消费者的附加元数据,请忽略它。
    • 我无法访问消费者,显然消费者正在像这样解析整个消息:<jms><queue>myque</queue>..</jms>my message 而我只是让他解析我的消息
    • hereThe MQRFH2 is optional, and its inclusion in an outgoing message is governed ... JMS Destination class. You can set this flag using the IBM MQ JMS administration tool. Because the MQRFH2 carries JMS-specific information, always include it in the message when the sender knows that the receiving destination is a JMS application. Normally, omit the MQRFH2 when sending a message directly to a non-JMS application. This is because such an application does not expect an MQRFH2 in its IBM MQ message
    【解决方案2】:

    您应该阅读目标客户端 - 请参阅 here

    有3种方法可以解决您的问题:

    (1) 使用 setTargetClient 方法,MQ 将剥离所有 JMS 标头(又名 MQRFH2 标头)并仅传递有效负载

    conn = mqQCF.createQueueConnection("MyUserId", "mypwd");
    conn.start();
    session = conn.createQueueSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
    myQ = session.createQueue("my.test.queue");
    MQDestination mqd = (MQDestination) myQ;
    mqd.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
    

    (2) 显式设置 MQ 队列名称和目标客户端(1 用于 MQ,0 用于 JMS 消息),MQ 将剥离所有 JMS 标头(又名 MQRFH2 标头)并仅传递有效负载

    conn = mqQCF.createQueueConnection("MyUserId", "mypwd");
    conn.start();
    session = conn.createQueueSession(true, 0);
    queue = queueSession.createQueue("queue://MQA1/TEST.Q1?targetClient=1");
    sender = queueSession.createSender(queue);
    

    (3) 在 MQ JNDI 中设置目标客户端,MQ 将剥离所有 JMS 标头(又名 MQRFH2 标头)并仅传递有效负载

    DEFINE Q(my.test.queue) QUEUE(TEST.Q1) QMANAGER(MQA1) TARGCLIENT(MQ) FAILIFQUIESCE(YES)
    

    【讨论】:

      【解决方案3】:

      您可以改为将 IBM MQ 队列管理器上的队列更改为使用 PROPCTL(NONE),而不是将 targetClient 设置为指示 MQ 使用者。这意味着任何无法处理属性的消费者在消费消息时都不会得到它们。

      你没有说消费者是什么类型的应用程序。

      【讨论】:

        猜你喜欢
        • 2016-05-02
        • 2015-08-25
        • 1970-01-01
        • 2011-01-11
        • 1970-01-01
        • 2015-02-19
        • 1970-01-01
        • 2016-12-10
        • 2011-08-20
        相关资源
        最近更新 更多