以字符串格式获取MQ messageId

Jim*_*myD 4 java ibm-mq

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

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

我尝试了几次转换,但没有一个有效:

new String(theMessage.messageId)
new String(theMessage.messageId, "UTF-8")
new String(theMessage.messageId, "UTF-16")
theMessage.messageId.toString()
Run Code Online (Sandbox Code Playgroud)

Jos*_*hMc 7

MQMD 中的 messageId 表示为 24 个字节。如果您知道这些是在什么平台上生成的,您可以通过将字节转换为生成它们的队列管理器的字符集中的字符来找到它们的某些部分的某些含义,但不建议依赖任何传输的数据在 messageID 中作为字符数据,因为我看到来自 IBM 的声明类似于“MsgId 由 MQ 以 IBM 专有格式生成,它可能随时更改”。

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

以下是getHexStringIBM 在技术说明中提供的示例函数,它将为您执行此转换。你会像这样使用它:

getHexString(theMessage.messageId)
Run Code Online (Sandbox Code Playgroud)

下面的示例函数来自 IBM MQ 技术说明“当通过 JMS 应用程序发出请求并从基本 Java API 生成回复时如何匹配相关 ID

public static String getHexString(byte[] b) throws Exception {
    String result = "";
    for (int i=0; i < b.length; i++) {
        result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

IBM 在知识中心页面底部记录了队列管理器生成的消息 ID 的格式和唯一性“参考>开发应用程序参考>MQI 应用程序参考>MQI 中使用的数据类型>MQMD - 消息描述符>字段>MsgId (MQBYTE24)

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


Rog*_*ger 5

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

您需要使用我的 bytesToHex 方法:

String s = bytesToHex(theMessage.messageId);
Run Code Online (Sandbox Code Playgroud)

因此,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);
}
Run Code Online (Sandbox Code Playgroud)

更新于 2020 年 7 月 23 日。

下面是将十六进制字符串转换为字节数组的方法:

public static byte[] hexStringToByteArray(String inString)
{
   byte[] outBuffer = new byte[inString.length()/2];
   String hex;
   int xx;

   for (int i=0, j=0; j < (inString.length() - 1); i++, j+=2)
   {
      hex = inString.substring(j,j+2);
      xx = Integer.parseInt(hex.trim(), 16);
      if (xx < 0)
         xx += 256;

      outBuffer[i] = (byte)xx;
   }

   return outBuffer;
}
Run Code Online (Sandbox Code Playgroud)