首页 > 解决方案 > 大型机 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

标签: jmsibm-mqebcdic

解决方案


关于 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


推荐阅读