代码之家  ›  专栏  ›  技术社区  ›  JimmyD

获取字符串格式的MQ messageId

  •  4
  • JimmyD  · 技术社区  · 9 年前

    如何将messageId从字节[]转换为字符串?

    我尝试了几个转换,但没有一个成功:

    new String(theMessage.messageId)
    new String(theMessage.messageId, "UTF-8")
    new String(theMessage.messageId, "UTF-16")
    theMessage.messageId.toString()
    
    3 回复  |  直到 9 年前
        1
  •  7
  •   JoshMc    6 年前

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

    下面是一个示例函数 getHexString IBM在技术说明中提供了将为您执行此转换的技术。您可以这样使用它:

    getHexString(theMessage.messageId)
    

    下面的示例函数来自IBM MQ Technote“ 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;
    }
    

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

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

        2
  •  4
  •   Roger    6 年前

    您需要使用我的bytesToHex方法:

    String s = bytesToHex(theMessage.messageId);
    

    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日更新。

    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;
    }
    
        3
  •  1
  •   cptully    6 年前

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

    import org.apache.commons.codec.binary.Hex;
    
    String mqMessageId = Hex.encodeHexString(message.messageId);
    message.messageId = Hex.decodeHex(mqMessageId.toCharArray());
    

    尽管如此,我还是想感谢罗杰的上述评论,因为他们让我走上了通向Apache Commons编解码器的道路。