【问题标题】:Websphere MQ: reading from DLQ with JMSWebsphere MQ:使用 JMS 从 DLQ 读取
【发布时间】:2020-03-05 01:57:35
【问题描述】:

我必须使用 JMS API 处理死信队列 (DLQ) 中的消息。目标是读取原始消息的正文及其用户属性。我意识到这种 DLQ 处理方法可能被认为是糟糕的设计,但无论如何我都必须处理它。

使用 JMS 读取后,DLQ 消息的正文包含原始消息的正文,前面带有 DL 标头和与原始消息的 RFH2 标头非常相似的结构(因此包含所有需要的用户属性)。

问题是,如何在java中解析这2个结构?

但我只找到了一个关于如何从原始数据构建 DLH 的文档 (https://www.ibm.com/support/knowledgecenter/SS8JB4/com.ibm.wbpm.main.doc/topics/esbprog_bindings_wmq5.html)。但是,虽然 DLH 似乎是一个固定长度的结构,但 RFH2 绝对不是——所以解析中最棘手的部分就在那里。

任何想法都将不胜感激。

更新

这是我发现的:

1) DLH是从原始字节数组中解析出来的,没有任何问题,简单如下:

MQDLH rfh = new MQDLH(new DataInputStream(new ByteArrayInputStream(bytes)));

一旦构建,所有属性都可用。

2) MQRFH2 可以以类似的方式创建,如果 MQLONG 值像往常一样以大端写入在那里。但出于某种原因,我完全不清楚,在这种情况下,所有 MQLONG 都是小端。

因此,要从原始字节创建 MQRFH2,我必须反转所有 MQLONG 的字节。固定部分不是问题(如https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032000_.htm 中所述),但可变部分有点复杂。

我没有在文档中看到任何确认,但似乎可变部分中的每个文件夹都以包含文件夹长度的 MQLONG(嗯,只是 4 字节整数)开头。一旦这些值也从 LE 转换为 BE,MQRFH2 似乎工作正常。

【问题讨论】:

    标签: java jms ibm-mq dead-letter


    【解决方案1】:

    我不会使用 JMS 应用程序处理 DLQ。它会如此,如此棘手,你将花费数天或数周的时间试图让它正确。我会编写一个普通的 Java 应用程序来完成它,要简单得多。

    MQMessage rcvMsg = new MQMessage();
    MQDLH dlh = new MQDLH(rcvMsg);
    MQRFH2 rfh2 = new MQRFH2(rcvMsg);
    byte[] bData = new byte[rcvMsg.getDataLength()];
    rcvMsg.readFully(bData);
    

    于 2020 年 3 月 4 日更新。

    我通常不会把头撞到墙上,但如果你愿意,那么这里是我会尝试的代码:

    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
    DataInput di = new DataInputStream(bais);
    
    MQDLH dlh = new MQDLH(di);
    MQRFH2 rfh2 = new MQRFH2(di)
    
    // Get all folders
    String[] folderStrings = rfh2.getFolderStrings();
    
    // or you can get individual name/values using
    // get***FieldValue() methods of the MQRFH2 class.
    
    /*
     * At this point, the cursor for "di" is pointing
     * to the beginning of the message payload and I
     * would normal do:
     */
    byte[] bData = new byte[mqMsg.getDataLength()];
    mqMsg.readFully(bData);
    

    【讨论】:

    • 我想过使用MQI,但主要问题是我不能在XA事务中使用MQI,这基本上是必需的。
    • 或者另一种选择可能是使用 MQI 读取并尝试使用 MQI 将“原始”消息(使用 JMS 可读)也放入另一个队列,但它的代价是增加一个应用程序。不太确定...
    • @Roger,我已经更新了这个问题。如果您发现这种方法有任何问题,请留言。除了它很脏的事实)
    • 查看我的更新。此外,如果您从 DLQ 移动消息,则不需要 XA。只需使用 MQ API 的提交和/或回退。
    猜你喜欢
    • 2010-10-28
    • 2012-08-27
    • 2015-06-19
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    • 2011-03-28
    相关资源
    最近更新 更多