【发布时间】:2020-05-06 19:26:05
【问题描述】:
我正在尝试从 Java 应用程序浏览大型机 IBM MQ 队列中的消息(EBCDIC 消息)。我需要浏览消息,而不是消费它们。代码如下:
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set properties
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, host);
cf.setIntProperty(WMQConstants.WMQ_PORT, port);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, qmgr);
cf.setIntProperty(WMQConstants.WMQ_RECEIVE_CONVERSION, WMQConstants.WMQ_RECEIVE_CONVERSION_QMGR);
QueueBrowser browser = context.createBrowser(context.createQueue("queue:///" + queueName + "?targetClient=1"));
Enumeration enumeration = browser.getEnumeration();
while (enumeration.hasMoreElements()) {
TextMessage messageInTheQueue = (TextMessage) enumeration.nextElement();
System.out.println(messageInTheQueue);
nbRecords++;
}
System.out.println() 的结果如下:
JMSMessage class: jms_text
JMSType: null
JMSDeliveryMode: 2
JMSMessageID: ID:c1d4d840d4d8e3c1e2f24040404040405e2432bd21aa1b02
JMSTimestamp: 1579537307450
JMSRedelivered: false
JMSXAppID:
JMSXDeliveryCount: 1
JMSXUserID:
JMS_IBM_Character_Set: IBM037
JMS_IBM_Encoding: 273
JMS_IBM_Format: MQSTR
JMS_IBM_MsgType: 8
JMS_IBM_PutApplType: 8
JMS_IBM_PutDate: 20200120
JMS_IBM_PutTime: 16214745
ÍÍÑÀ ...
我想将此 EBCDIC 消息 ÍÍÑÀ ... 转换为可读的 (ASCII)。
我尝试将 enumeration.nextElement() 转换为 JMSByteMessage 但得到了这个异常:
class com.ibm.msg.client.jms.internal.JmsTextMessageImpl cannot be cast to class com.ibm.jms.JMSBytesMessage
我该怎么做?
解决方案: 使用 Java 的 MQ 类 而不是 Java 的 MQ JMS 类:
byte[] strData = new byte[theMessage.getMessageLength()];
theMessage.readFully(strData, 0, theMessage.getMessageLength());
这里有一些例子:https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q030840_.htm
【问题讨论】:
-
你试过没有
cf.setIntProperty(WMQConstants.WMQ_RECEIVE_CONVERSION, WMQConstants.WMQ_RECEIVE_CONVERSION_QMGR);吗?请注意,targetClient与生产者而非接收者相关,它可能对您设置的上下文没有影响。 -
您是否直接连接到大型机?我相信如果您不设置 CCSID,CCSID 将默认为队列管理器的 CCSID 以用于
WMQ_RECEIVE_CONVERSION_QMGR。如果未设置WMQ_RECEIVE_CONVERSION,则默认应由IBM MQ 类JMS 进行转换,此转换的CCSID 目标通常为1208,即UTF-8。我认为如果你不设置WMQ_RECEIVE_CONVERSION,你应该得到你可以阅读的文本,或者将你的CCSID设置为1208,看看队列管理器是否可以转换它。 -
我尝试了设置和不设置
WMQ_RECEIVE_CONVERSION,但结果是一样的,仍然没有可读的'UTF-8'。我认为enumeration.nextElement();只返回文本JMSTextMessage。根据:ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/… 我需要一个JMSBytesMessage,这样我才能执行转换。 -
如果您使用的是 IBM MQ jar 文件是什么版本?
-
我终于切换到
com.ibm.mq罐子,而不是com.ibm.msg.client.jms和com.ibm.jms。在这种情况下,不再有 JMS 层。这是我使用的代码:ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/… 基本上使用这个解决方案,我能够获得一个字节数组并转换为字符串:byte[] strData = new byte[theMessage.getMessageLength()]; theMessage.readFully(strData, 0, theMessage.getMessageLength());我用这个解决方案编辑了原始帖子。