获取字符串格式的 MQ messageId
Get MQ messageId in string format
我正在使用 IBM 的 mq 库从 MQ queues 读取消息。现在我需要检索消息的 messageid。我现在它在消息 header 中,名称为 messageId。但是这个returns一个byte[]。现在我需要将其更改为可读字符串。
如何将 messageId 从 byte[] 转换为字符串?
我尝试了几次转换,但没有一个有效:
new String(theMessage.messageId)
new String(theMessage.messageId, "UTF-8")
new String(theMessage.messageId, "UTF-16")
theMessage.messageId.toString()
MQMD MessageId 字段由字符值和二进制值组成。因此,将 MessageId 字段正确表示为字符串的唯一方法是将其转换为十六进制表示。
你需要使用我的 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);
}
2020 年 7 月 23 日更新。
这是一个将 HEX 字符串转换为字节数组的方法:
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;
}
MQMD中的messageId表示为24字节。如果您知道这些是在哪个平台上生成的,您可以通过将字节转换为生成它们的队列管理器的字符集中的字符来找到它们的某些部分的某些含义,但不建议依赖于任何正在传送的数据在 messageID 中作为字符数据,因为我看到 IBM 的声明类似于“MsgId 是由 MQ 以 IBM 专有格式生成的,它可能随时更改。”
如果您想将它们表示为字符串,您应该将它们表示为代表 24 个字节的 48 个字符的十六进制字符串。
下面是一个示例函数 getHexString
IBM 在技术说明中提供了一个将为您执行此转换的函数。你会像这样使用它:
getHexString(theMessage.messageId)
下面的示例函数来自 IBM MQ 技术说明“How to match correlation id's when request is made via JMS application and reply generated from base Java API”
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;
}
底部记录了队列管理器生成的消息 ID 的格式和唯一性
A MsgId generated by the queue manager consists of a 4-byte product identifier (AMQ¬ or CSQ¬ in either ASCII or EBCDIC, where ¬ represents a blank character), followed by a product-specific implementation of a unique string. In IBM® MQ this contains the first 12 characters of the queue-manager name, and a value derived from the system clock. All queue managers that can intercommunicate must therefore have names that differ in the first 12 characters, in order to ensure that message identifiers are unique. The ability to generate a unique string also depends on the system clock not being changed backward. To eliminate the possibility of a message identifier generated by the queue manager duplicating one generated by the application, the application must avoid generating identifiers with initial characters in the range A through I in ASCII or EBCDIC (X'41' through X'49' and X'C1' through X'C9'). However, the application is not prevented from generating identifiers with initial characters in these ranges.
我已经成功实现了获取MQ MessageId并转换为十六进制字符串本地存储,然后在稍后再次使用它查询MQ时将其转换回byte[]的循环,使用Apache Commons Codec 因此:
import org.apache.commons.codec.binary.Hex;
String mqMessageId = Hex.encodeHexString(message.messageId);
message.messageId = Hex.decodeHex(mqMessageId.toCharArray());
我喜欢这种方法,因为它依赖于知名且受人尊敬的组织维护良好的库,而且我不必维护任何其他方法。
None 我越不想感谢 Roger 上面的评论,因为它们让我走上了通向 Apache Commons Codec 的道路。
我正在使用 IBM 的 mq 库从 MQ queues 读取消息。现在我需要检索消息的 messageid。我现在它在消息 header 中,名称为 messageId。但是这个returns一个byte[]。现在我需要将其更改为可读字符串。
如何将 messageId 从 byte[] 转换为字符串?
我尝试了几次转换,但没有一个有效:
new String(theMessage.messageId)
new String(theMessage.messageId, "UTF-8")
new String(theMessage.messageId, "UTF-16")
theMessage.messageId.toString()
MQMD MessageId 字段由字符值和二进制值组成。因此,将 MessageId 字段正确表示为字符串的唯一方法是将其转换为十六进制表示。
你需要使用我的 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);
}
2020 年 7 月 23 日更新。
这是一个将 HEX 字符串转换为字节数组的方法:
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;
}
MQMD中的messageId表示为24字节。如果您知道这些是在哪个平台上生成的,您可以通过将字节转换为生成它们的队列管理器的字符集中的字符来找到它们的某些部分的某些含义,但不建议依赖于任何正在传送的数据在 messageID 中作为字符数据,因为我看到 IBM 的声明类似于“MsgId 是由 MQ 以 IBM 专有格式生成的,它可能随时更改。”
如果您想将它们表示为字符串,您应该将它们表示为代表 24 个字节的 48 个字符的十六进制字符串。
下面是一个示例函数 getHexString
IBM 在技术说明中提供了一个将为您执行此转换的函数。你会像这样使用它:
getHexString(theMessage.messageId)
下面的示例函数来自 IBM MQ 技术说明“How to match correlation id's when request is made via JMS application and reply generated from base Java API”
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;
}
底部记录了队列管理器生成的消息 ID 的格式和唯一性
A MsgId generated by the queue manager consists of a 4-byte product identifier (AMQ¬ or CSQ¬ in either ASCII or EBCDIC, where ¬ represents a blank character), followed by a product-specific implementation of a unique string. In IBM® MQ this contains the first 12 characters of the queue-manager name, and a value derived from the system clock. All queue managers that can intercommunicate must therefore have names that differ in the first 12 characters, in order to ensure that message identifiers are unique. The ability to generate a unique string also depends on the system clock not being changed backward. To eliminate the possibility of a message identifier generated by the queue manager duplicating one generated by the application, the application must avoid generating identifiers with initial characters in the range A through I in ASCII or EBCDIC (X'41' through X'49' and X'C1' through X'C9'). However, the application is not prevented from generating identifiers with initial characters in these ranges.
我已经成功实现了获取MQ MessageId并转换为十六进制字符串本地存储,然后在稍后再次使用它查询MQ时将其转换回byte[]的循环,使用Apache Commons Codec 因此:
import org.apache.commons.codec.binary.Hex;
String mqMessageId = Hex.encodeHexString(message.messageId);
message.messageId = Hex.decodeHex(mqMessageId.toCharArray());
我喜欢这种方法,因为它依赖于知名且受人尊敬的组织维护良好的库,而且我不必维护任何其他方法。
None 我越不想感谢 Roger 上面的评论,因为它们让我走上了通向 Apache Commons Codec 的道路。