简体   繁体   English

Websphere MQ:使用 JMS 从 DLQ 读取

[英]Websphere MQ: reading from DLQ with JMS

I have to process messages in Dead Letter Queue (DLQ) using JMS API.我必须使用 JMS API 处理死信队列 (DLQ) 中的消息。 The goal is to read body of the original messages and it's user properties.目标是读取原始消息的正文及其用户属性。 I realize that such approach to DLQ processing might be considered as bad design, but I have to deal with it anyway.我意识到这种 DLQ 处理方法可能被认为是糟糕的设计,但无论如何我都必须处理它。

Once read with JMS, body of DLQ message contains body of the original one, prepended with DL header and a structure very similar to RFH2 header of the original message (so containing all the needed user properties).一旦用 JMS 读取,DLQ 消息的正文包含原始消息的正文,加上 DL 标头和与原始消息的 RFH2 标头非常相似的结构(因此包含所有需要的用户属性)。

The question is, how to parse these 2 structures in java?问题是,如何在java中解析这两个结构?

Yet I only found a doc about how DLH could be constructed from raw data ( https://www.ibm.com/support/knowledgecenter/SS8JB4/com.ibm.wbpm.main.doc/topics/esbprog_bindings_wmq5.html ).然而,我只找到了关于如何从原始数据构建 DLH 的文档( https://www.ibm.com/support/knowledgecenter/SS8JB4/com.ibm.wbpm.main.doc/topics/esbprog_bindings_wmq5.html )。 But while DLH seems to be a fixed-lenght structure, RFH2 is definitely not - so the most tricky part of parsing is there.但是虽然 DLH 似乎是一个固定长度的结构,但 RFH2 绝对不是——所以解析中最棘手的部分就在那里。

Any idea would be appreciated.任何想法将不胜感激。

UPDATE更新

Here is what I have found:这是我发现的:

1) DLH was parsed from raw byte array without any problem, as simple as follows: 1)DLH是从原始字节数组中解析出来的,没有任何问题,简单如下:

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

Once constructed, all the properties are available.构建完成后,所有属性都可用。

2) MQRFH2 could be created in a similar manner, if MQLONG values were written there as usual, in big endian. 2) MQRFH2 可以以类似的方式创建,如果 MQLONG 值像往常一样以大端格式写入那里。 But for some reason, completely unclear to me, in this case all MQLONG are little endian.但出于某种原因,我完全不清楚,在这种情况下,所有 MQLONG 都是小端。

So, to create MQRFH2 from raw bytes I have to reverse bytes for all MQLONGs.因此,要从原始字节创建 MQRFH2,我必须反转所有 MQLONG 的字节。 Not a problem for a fixed part (as described in https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032000_.htm ), but a bit more complicated for variable part.固定部分不是问题(如https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032000_.htm 中所述),但对于可变部分。

I haven't seen any confirmation in docs, but it seems that each folder in variable part is prepended with MQLONG (well, just 4-bytes integer) containing folder length.我还没有在文档中看到任何确认,但似乎可变部分中的每个文件夹都带有包含文件夹长度的 MQLONG(好吧,只是 4 字节整数)。 Once these values were converted from LE to BE as well, MQRFH2 seem to be working correctly.一旦这些值也从 LE 转换为 BE,MQRFH2 似乎工作正常。

I wouldn't process the DLQ with a JMS application.我不会用 JMS 应用程序处理 DLQ。 It will be so, so tricky and you will spend days or weeks trying to get it right.它会如此,如此棘手,您将花费数天或数周的时间来尝试正确处理。 I would write a regular Java application to do it, far simpler.我会编写一个普通的 Java 应用程序来完成它,这要简单得多。

ie IE

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

Updated on March 4, 2020. 2020 年 3 月 4 日更新。

I am normally not into banging my head against the wall but if you want to then here is the code that I would try:我通常不会把头撞在墙上,但如果你愿意,那么这里是我会尝试的代码:

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM