1

我在从接收到的属性中读取属性时遇到了一个大问题MQMessage(我使用的是 WebSphere MQ 7.5 客户端)。访问某些属性时GetObjectProperty会引发MQRC_PROPERTY_NOT_AVAILABLE错误。我将尝试解释我的日志记录代码中的错误。

我在应用程序中有一些日志记录工具。此工具还可以选择转储所有已处理的 MQ 消息。转储包含消息正文、来自 MQMD 的所有标准消息头以及所有其他 JMS 或用户属性。转储属性时会导致问题,因为GetPropertyNames("%")返回消息中“不存在”的属性名称 -GetObjectProeprty使用此类名称调用会导致MQException原因代码 2471 - MQRC_PROPERTY_NOT_AVAILABLE

这是我的转储属性方法的简化代码:

private static void DumpMessageProperties(MQMessage message, StringBuilder dumpBuilder) {
    IEnumerator names = message.GetPropertyNames("%");
    dumpBuilder.AppendLine("Properties:");
    while (names.MoveNext()) {
        string name = names.Current.ToString();
        dumpBuilder.AppendFormat("  {0}: ", name);

        try {
            object value = message.GetObjectProperty(name);

            if (value != null) {
                Type type = value.GetType();
                if (type != typeof(sbyte[])) {
                    if (type == typeof(string)) {
                        string strValue = value.ToString();
                        dumpBuilder.Append(String.Format("\"{0}\" [{1}]", strValue, type));
                    } else {
                        dumpBuilder.Append(String.Format("{0} [{1}]", value, type));
                    }
                } else {
                    dumpBuilder.Append(String.Format("{0}", DumpSByteArray((sbyte[])value)));
                }
            }
        } catch (MQException e) {
            dumpBuilder.AppendFormat("{0} ({1})", e.Message, e.ReasonCode.ToString());
        }

        dumpBuilder.AppendLine();
    }
}

我偶尔会MQRC_PROPERTY_NOT_AVAILABLE在转储接收或发送消息的用户属性时得到。收到消息时转储失败的示例:

Properties:
  JMSReplyTo: "queue:///SomeQueue" [System.String]
  Encoding: MQRC_PROPERTY_NOT_AVAILABLE (2471)
  JMSDeliveryMode: 0 [System.Int32]
  CodedCharSetId: MQRC_PROPERTY_NOT_AVAILABLE (2471)
  JMSDestination: "queue:///SomeReplyQueue" [System.String]
  MessageVersion: "001" [System.String]
  mcd.Msd: "jms_text" [System.String]
  MessageName: "SomeMessageName" [System.String]

看起来 MQRFH2 标头中的控制字段以某种方式传递到消息中。我以为客户端会自动处理 MQRFH2 消息格式并为我翻译。

已发送消息转储失败的示例:

Properties:
  JMSTimestamp: MQRC_PROPERTY_NOT_AVAILABLE (2471)
  mcd.Msd: 
  JMSDestination: MQRC_PROPERTY_NOT_AVAILABLE (2471)
  JMSReplyTo: MQRC_PROPERTY_NOT_AVAILABLE (2471)
  JMSDeliveryMode: 1 [System.Int32]

为什么会这样?我检查了错误的文档,但我仍然不明白如何避免错误并简单地获取这些数据或如何摆脱不应成为消息一部分的属性(RFH 控制字段,如EncodingCodeCharSetId

这看起来MQMessage处于不一致的状态。

4

1 回答 1

0

我认为您应该仅从 MQRFH2 标头中读取属性。我就是这样做的:

MQRFH2 rfh2 = null;

// Find and store message length
int msglen = replyMessage.getMessageLength();

MQHeaderList list = new MQHeaderList(replyMessage);
int indexOf = list.indexOf("MQRFH2");
if (indexOf >= 0) {
    rfh2 = (MQRFH2) list.get(indexOf);
    msglen = msglen - header.size();
}

// this will hold the message text
String msgText = replyMessage.readStringOfCharLength(msglen);

// this will hold all the properties in the end
Map<String, Object> headers = new TreeMap<String, Object>();

if (rfh2 != null) {
    try {
        for (Element folder : rfh2.getFolders()) {
            String prefix = folder.getName() + ".";
            for (Element element : folder.getChildren()) {
                headers.put(prefix + element.getName(), element.getValue());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

虽然这是 Java,但我确信有一种类似的方法可以使用 .net 来实现。

希望它会有所帮助。

于 2013-06-17T11:54:22.923 回答