jms - 大型机 MQ 到 EBCDIC 中的独立 JMS
问题描述
我正在尝试从 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
解决方案
关于 OP 的原始代码,以下文档状态接收转换和 CCSID 仅对 MQDestination 类有效:https ://www.ibm.com/docs/en/ibm-mq/9.2?topic=reference-properties-mq -classes-jms-对象
因此,这可以通过 IBM MQ Classes for JMS 来完成。你只需要以一种更迂回的方式来做。
为了让 QueueBrowser 读取 EBCDIC 格式的消息,您需要将 JMS Queue 转换为 MQDestination,然后设置 receiveConversion 和 receiveCCSID,然后在创建浏览器时,将 MQDestination 转换回常规 JMS Queue。像这样:
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);
JMSContext context = cf.createContext();
MQDestination targetQueue = (MQDestination) context.createQueue("queue:///" + queueName)
targetQueue.setReceiveCCSID(WMQConstants.CCSID_UTF8);
targetQueue.setReceiveConversion(WMQConstants.WMQ_RECEIVE_CONVERSION_QMGR);
targetQueue.setMessageBodyStyle(WMQConstants.WMQ_MESSAGE_BODY_MQ);
QueueBrowser browser = context.createBrowser((Queue) targetQueue);
Enumeration enumeration = browser.getEnumeration();
while (enumeration.hasMoreElements()) {
TextMessage messageInTheQueue = (TextMessage) enumeration.nextElement();
System.out.println(messageInTheQueue);
nbRecords++;
}
这样做时,您也不需要使用 JMS URI 属性来设置目标客户端,因为 MQDestination 具有所有必要的 getter/setter 来修改本来可以使用 URI 完成的属性负载。
有关 MQDestination 的更多信息,请参阅以下文档:https ://www.ibm.com/docs/en/ibm-mq/9.2?topic=jms-mqdestination