以字符串格式获取MQ messageId

时间:2017-08-17 07:40:43

标签: java ibm-mq

我正在使用IBM的mq库来读取MQ队列中的消息。现在我需要检索消息的messageid。我现在它在名为messageId的消息头中。但这会返回一个byte []。现在我需要将其更改为可读字符串。

如何将messageId从byte []转换为string?

我尝试了几次转换,但没有转化:

new String(theMessage.messageId)
new String(theMessage.messageId, "UTF-8")
new String(theMessage.messageId, "UTF-16")
theMessage.messageId.toString()

3 个答案:

答案 0 :(得分:2)

MQMD中的messageId表示为24个字节。如果您知道这些生成的平台,您可以通过将字节转换为生成它们的队列管理器的字符集中的字符来为它们的某些部分找到一些含义,但不建议依赖于传输的任何数据在messageID中作为字符数据,因为我看到IBM的语句类似于“MsgId is generated by MQ in an IBM proprietary format and it may change at any time.

如果要将它们表示为字符串,则应将它们表示为48个字符的HEX字符串,表示24个字节。

以下是IBM在Technote中提供的示例函数--conf "spark.executor.extraLibraryPath=/local/path/to/so" \ --conf "spark.driver.extraLibraryPath=/local/path/to/so" ,它将为您执行此转换。你可以这样使用它:

getHexString

以下示例函数来自IBM MQ Technote“How to match correlation id's when request is made via JMS application and reply generated from base Java API

getHexString(theMessage.messageId)

IBM记录知识中心页面“Reference>Developing applications reference>MQI applications reference>Data types used in the MQI>MQMD - Message descriptor>Fields>MsgId (MQBYTE24)”底部的队列管理器生成的消息ID的格式和唯一性

  

队列管理器生成的MsgId由4字节的产品标识符(ASCII或EBCDIC中的AMQ或CSQ,其中¬表示空白字符)组成,后跟特定字符串的产品特定实现。在IBM®MQ中,它包含队列管理器名称的前12个字符,以及从系统时钟派生的值。因此,所有可以相互通信的队列管理器必须具有前12个字符不同的名称,以确保消息标识符是唯一的。生成唯一字符串的能力还取决于系统时钟不向后更改。为了消除由队列管理器生成的消息标识符复制应用程序生成的消息标识符的可能性,应用程序必须避免生成带有ASCII或EBCDIC(X'41'到X'49'中的A到I范围内的初始字符的标识符。 X'C1'到X'C9')。但是,不会阻止应用程序生成具有这些范围内的初始字符的标识符。

答案 1 :(得分:1)

MQMD MessageId字段由字符和二进制值组成。因此,将MessageId字段正确表示为String的唯一方法是将其转换为HEX表示。

您需要使用我的bytesToHex方法:

String s = bytesToHex(theMessage.messageId);

因此,s看起来像'414D51204D5141312020202020202020134CCD4020000B01'。

bytesToHex方法的Java代码是:

public static final String HEX_CHARS = "0123456789ABCDEF";

public static String bytesToHex(byte[] data)
{
   StringBuffer buf = new StringBuffer();
   for (int i = 0; i < data.length; i++)
      buf.append(byteToHex(data[i]));

   return buf.toString();
}

public static String byteToHex(byte data)
{
   int hi = (data & 0xF0) >> 4;
   int lo = (data & 0x0F);
   return "" + HEX_CHARS.charAt(hi) + HEX_CHARS.charAt(lo);
}

答案 2 :(得分:1)

我已经成功实现了以下过程:获取MQ MessageId并将其转换为用于本地存储的十六进制字符串,然后在以后使用它使用Apache Commons Codec再次查询MQ时将其转换回byte []。因此:

import org.apache.commons.codec.binary.Hex;

String mqMessageId = Hex.encodeHexString(message.messageId);
message.messageId = Hex.decodeHex(mqMessageId.toCharArray());

我喜欢这种方法,因为它依赖于来自知名且受人尊敬的组织的维护良好的库,而且我不必维护任何其他方法。

我还是要感谢罗杰的上述评论,因为它们使我走上了通往Apache Commons Codec的道路。