IBM MQ Java读取消息格式不正确。

huangapple go评论65阅读模式
英文:

IBM MQ Java read msg Format incorrect

问题

I want to read data from queue of MQ.
When I browse queue in MQExplorer I find messages with Format=MQSTR.

但当我读取它们时,格式变成了MQHRF2!
我的MQ服务器是MQ7.5,并使用com.ibm.mq.allclient的Maven库。

MQMessage getMessage = new MQMessage();
getMessage.clearMessage();
MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
queue.get(getMessage, mqGetMessageOptions);
String format = getMessage.format.trim();

我在其他服务器和队列上尝试过我的源代码,它正常运行(获取MQSTR)。

英文:

I want to read data from queue of MQ.
When I browse queue in MQExplorer I find messages with Format=MQSTR.

IBM MQ Java读取消息格式不正确。

But when I read them, Format is MQHRF2 !!
My MQ server is MQ7.5 and use com.ibm.mq.allclient maven library.

MQMessage getMessage = new MQMessage();
getMessage.clearMessage();
MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions();
queue.get(getMessage, mqGetMessageOptions);
String format = getMessage.format.trim();

I tried my source on other server and queue and works well (get MQSTR).

答案1

得分: 2

以下是您要翻译的内容:

需要理解整体情况,然后编码才会有意义。

JMS消息实际上是IBM MQ内部的MQRFH2消息。因此,IBM允许客户端应用以两种格式之一接收JMS消息,即JMS消息或MQRFH2消息。

  • JMS消息意味着消息的MQMD.Format将是'MQSTR',并且将具有命名属性(又称消息属性)。
  • MQRFH2消息意味着消息的MQMD.Format将是'MQHRF2',并且将具有包含命名属性(又称消息属性)的嵌入式MQHRF2结构。

因此,如果要使客户端应用接收JMS消息,可以编写以下代码:

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_IN_HANDLE + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

另一方面,如果要使客户端应用接收MQRFH2消息,可以编写以下代码:

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_FORCE_MQRFH2 + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

如果选择MQRFH2消息,仍然可以使用MQRFH类访问消息负载中的命名属性。注意:用户/应用程序属性存储在'usr'文件夹中。

MQRFH2 rfh2 = new MQRFH2(getMsg);
String value = rfh2.getStringFieldValue ("usr", "MyProp");

最后,对于MQ API调用,如MQOPEN、MQGET、MQPUT或MQPUT1,使用/编码'如果处于停机状态则失败'选项是MQ最佳实践。

即:

int openOptions = CMQC.MQOO_INPUT_AS_Q_DEF + CMQC.MQOO_FAIL_IF_QUIESCING;
MQQueue inQ = qMgr.accessQueue(inputQName, openOptions);
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_IN_HANDLE + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

和:

int openOptions = CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING;
MQQueue outQ = qMgr.accessQueue(outputQName, openOptions);
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = CMQC.MQPMO_FAIL_IF_QUIESCING;
MQMessage putMsg = new MQMessage();
putMsg.writeString("这是一条测试消息。");
outQ.put(putMsg, pmo);
英文:

You need to understand the big picture then the coding will make sense.

A JMS message is actually an MQRFH2 message to IBM MQ internally. So, IBM allows the client application to receive the JMS message in 1 of 2 formats. i.e. JMS message or MQRFH2 message.

  • A JMS message means that the message MQMD.Format will be 'MQSTR' and it will have Named Properties (aka Message Properties).
  • An MQRFH2 message means that the message MQMD.Format will be 'MQHRF2' and it will have an embedded MQHRF2 structure that will contain the Named Properties (aka Message Properties).

Therefore, if you want the client application to receive a JMS message then you can code the following:

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_IN_HANDLE + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

On the other hand, if you want the client application to receive an MQRFH2 message then you can code the following:

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_FORCE_MQRFH2 + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

If you go with the MQRFH2 message, you can still get access to the Named Properties in the message's payload by using the MQRFH class. Note: User/application properties are stored in the 'usr' folder.

MQRFH2 rfh2 = new MQRFH2(getMsg);
String value = rfh2.getStringFieldValue ("usr", "MyProp");

Finally, for MQ APIs calls like MQOPEN, MQGET, MQPUT or MQPUT1, it is MQ Best Practises to use/code the 'Fail if Quiescing' option.

i.e.

int openOptions  = CMQC.MQOO_INPUT_AS_Q_DEF + CMQC.MQOO_FAIL_IF_QUIESCING;
MQQueue inQ = qMgr.accessQueue(inputQName, openOptions);
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_IN_HANDLE + CMQC.MQGMO_FAIL_IF_QUIESCING;
MQMessage getMsg = new MQMessage();
inQ.get(getMsg, gmo);

And:

int openOptions = CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING;
MQQueue outQ = qMgr.accessQueue(outputQName, openOptions);
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = CMQC.MQPMO_FAIL_IF_QUIESCING;
MQMessage putMsg = new MQMessage();
putMsg.writeString("This is a test message.");
outQ.put(putMsg, pmo);

huangapple
  • 本文由 发表于 2023年4月19日 17:34:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052941.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定