从接收到的MQMessage
读取属性时我遇到了一个大问题(我正在使用WebSphere MQ 7.5 Client)。使用GetObjectProperty
访问某些属性会触发MQRC_PROPERTY_NOT_AVAILABLE
错误。我将尝试解释日志代码中的错误。
我在应用程序中有一些日志工具。此工具还可以选择转储所有已处理的MQ消息。转储包含消息正文,来自MQMD的所有标准消息头以及所有其他JMS或用户属性。转储属性时会导致此问题,因为GetPropertyNames("%")
返回消息中“不存在”的属性名称 - 使用此类名称调用GetObjectProeprty
会导致MQException
,原因代码为2471 - {{ 1}}。
以下是我的转储属性方法的简化代码:
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
看起来MQRFH2标头中的控制字段以某种方式传递到消息中。我以为客户端会自动处理MQRFH2消息格式并为我翻译。
已发送邮件的转储失败示例:
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]
为什么会这样?我检查了the documentation for the error但我仍然不明白如何避免错误并简单地获取这些数据或如何摆脱不应该成为消息一部分的属性(RFH控制字段如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]
和Encoding
)。
这似乎CodeCharSetId
处于不一致状态。
答案 0 :(得分: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的方法。
希望它有所帮助。