java 无法通过ActiveMQ Artemis中的JMX读取字节消息

bxfogqkk  于 2023-05-21  发布在  Java
关注(0)|答案(1)|浏览(110)

我正在通过JMX阅读消息。如果它是文本,那么一切正常,但如果它是字节,那么它会给出这样的错误。我不知道如何读取字节消息并将其文本转换为字符串。
下面是我的Java代码:

public static JMXMessage showMessage(QueueControl queueControl) {
    JMXHeaders jmxHeaders;
    JMXMessage jmxMessage;
    String body;
    String replyTo = null;
    String correlationId = null;
    try {
        CompositeData[] messages = queueControl.browse();
        j = queueLength - i;
        if (j > queueLength - 1) {
            i = 1;
            j = queueLength - i;
        }
        if (j < 0) {
            i = queueLength;
            j = 0;
        }

        TabularData stringProps = (TabularData) messages[j].get(CompositeDataConstants.STRING_PROPERTIES);
        for (CompositeData o : (Collection<CompositeData>) stringProps.values()) {
            Object key = o.get("key");
            if (key.equals("JMSReplyTo")) {
                replyTo = o.get("value").toString();
            }
            if (key.equals("JMSCorrelationID")) {
                correlationId = o.get("value").toString();
            }
        }
        jmxHeaders = new JMXHeaders(messages[j].get(CompositeDataConstants.TYPE).toString(),
                messages[j].get(CompositeDataConstants.EXPIRATION).toString(),
                messages[j].get(CompositeDataConstants.DURABLE).toString(),
                replyTo,
                messages[j].get(CompositeDataConstants.MESSAGE_ID).toString(),
                messages[j].get(CompositeDataConstants.TIMESTAMP).toString(),
                correlationId,
                messages[j].get(CompositeDataConstants.PRIORITY).toString());
        body = (String) messages[j].get(CompositeDataConstants.TEXT_BODY);
        jmxMessage = new JMXMessage(jmxHeaders, body);

        return jmxMessage;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

错误代码:

Caused by: java.lang.RuntimeException: javax.management.openmbean.InvalidKeyException: Argument key="text" is not an existing item name for this CompositeData instance.
    at jmxClientUIPConsole.BuildGet.showMessage(BuildGet.java:155)
    at jmxClientUIPConsole.DConsoleFrameControllerGetMessage.viewMessage(DConsoleFrameControllerGetMessage.java:166)
    ... 62 more
Caused by: javax.management.openmbean.InvalidKeyException: Argument key="text" is not an existing item name for this CompositeData instance.
    at java.management/javax.management.openmbean.CompositeDataSupport.get(CompositeDataSupport.java:270)
    at jmxClientUIPConsole.BuildGet.showMessage(BuildGet.java:150)
    ... 63 more

这就是这一行的错误:

body = (String) messages[j].get(CompositeDataConstants.TEXT_BODY);

那么,我如何才能在这个方法中确定什么消息(字节或文本)到达我?如何从队列中获取以字节为单位的消息?

wpx232ag

wpx232ag1#

JMS BytesMessageTextMessage的主体序列化方式不同,因为前者是byte[],后者是String。您试图从不存在的BytesMessage中获取 text body,因此您收到InvalidKeyException
但是,您可以检测消息的类型,然后进行相应的调整,例如:

QueueControl queueControl = ...
      CompositeData[] messages = queueControl.browse();
      for (CompositeData message : messages) {
         if ((byte) message.get(CompositeDataConstants.TYPE) == (byte) 4) {
            System.out.println("This is a BytesMessage");
         } else {
            System.out.println("This is a TextMessage");
         }
      }

如果你想得到消息的byte[]体,你可以这样做:

byte[] body = (byte[]) message.get(CompositeDataConstants.BODY);

当然,为了真正地 * 解码 * 它们,例如将byte[]解码为String,您需要首先知道它是如何编码的。Java中的String对象可以用许多不同的方式编码,尽管最常见的可能是使用UTF-8,在这种情况下,代码看起来像这样:

String body = Strings.getString((byte[]) message.get(CompositeDataConstants.BODY), StandardCharsets.UTF_8);

相关问题