我正在使用 JMS 客户端。该队列是一个 IBM MQ。当我在队列上写入数据时,它会添加 RFH 标头。如何剥离 RFH 标头。我无法使用 IBM MQ API。
6 回答
另一种方法是使用队列 URI 属性(http://www.ibm.com/support/knowledgecenter/api/content/nl/en-us/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032240_.htm #q032240___q032240_4)。该属性targetClient
控制是使用 RFH 还是原生格式。
Queue queue = queueSession.createQueue("queue:///" + queueName + "?targetClient=1");
从 IBM WebSphere MQ v7 开始,告诉 Java 实现不生成 MQRFH2 标头的推荐方法是调用MQDestination.setMessageBodyStyle( WMQConstants.WMQ_MESSAGE_BODY_MQ)
,因为TARGCLIENT
属性仅MessageBodyStyle
在显式设置为时用作回退选项UNSPECIFIED
。
使用 JNDI 队列配置,您可以设置 targetClient=MQ,其效果与 targetClient=1 相同:
<jmsQueue jndiName="jms/queue/name">
<properties.wmqJms CCSID="819" baseQueueName="MQ.QUEUE.NAME" encoding="273" targetClient="MQ"/>
</jmsQueue>
您也可以在队列本身上设置PROPCTL
为NONE
,这将去除标题,但根据我的经验,最好通过应用程序配置来完成。
由于登陆此页面的一些读者实际上可以使用 IBM API,以下是我为 IBM MQ v8 发布消息的代码,用于不支持 RFH 标头的旧客户端。
package com.mycompany.mq.client;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Logger;
import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSConsumer;
import javax.jms.JMSContext;
import javax.jms.JMSProducer;
import javax.jms.Queue;
import javax.jms.TextMessage;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
import com.ibm.msg.client.wmq.compat.jms.internal.JMSC;
public class FileScanner {
private static final Logger logger = Logger.getLogger("RJEFileParser");
public final static char CR = (char) 0x0D;
public final static char LF = (char) 0x0A;
public final static String CRLF = "" + CR + LF; // "" forces conversion to string
public static void main(String[] args) throws Exception {
long m1,m2;
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
JmsConnectionFactory cf = ff.createConnectionFactory();
// Set the properties
String sHost=Config.get("HOST");
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME, sHost);
logger.info("WMQ_HOST_NAME:"+sHost);
String sPort=Config.get("PORT");
cf.setIntProperty(WMQConstants.WMQ_PORT, Integer.parseInt(sPort));
logger.info("WMQ_PORT:"+sPort);
String sChannel=Config.get("CHANNEL");
cf.setStringProperty(WMQConstants.WMQ_CHANNEL, sChannel);
logger.info("WMQ_CHANNEL:"+sChannel);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
String sQmgr=Config.get("QMGR");
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, sQmgr);
logger.info("WMQ_QUEUE_MANAGER:"+sQmgr);
String sAppName=Config.get("APPLICATION_NAME");
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, sAppName);
logger.info("WMQ_APPLICATIONNAME:"+sAppName);
boolean bAuth = Boolean.parseBoolean(Config.get("AUTH")); // true
boolean bMqcsp = Boolean.parseBoolean(Config.get("USER_AUTHENTICATION_MQCSP")); // false
String sAppUser = null, sAppPass = null;
logger.info("Auth:"+bAuth);
if (bAuth) {
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, bMqcsp);
logger.info("USER_AUTHENTICATION_MQCSP:"+bMqcsp);
if (!bMqcsp) {
sAppUser=Config.get("APP_USER");
cf.setStringProperty(WMQConstants.USERID, sAppUser);
logger.info("APP_USER:"+sAppUser);
sAppPass=Config.get("APP_PASSWORD");
cf.setStringProperty(WMQConstants.PASSWORD, sAppPass);
logger.info("APP_PASSWORD:"+sAppPass);
}
}
// Create JMS objects
try {
Connection con;
logger.info("Creating connection... context: \n"+ cf.toString());
if (bAuth && !bMqcsp) {
con = cf.createConnection(sAppUser, sAppPass);
}
else {
con = cf.createConnection();
}
con.close(); // connection was created for testing credentials and troubleshooting purposes
JMSContext context = cf.createContext();
//Set up the message
String text = "here goes your payload text" ;
logger.info("Text:"+text);
TextMessage message = context.createTextMessage(text);
// message.setIntProperty(WMQConstants.JMS_IBM_CHARACTER_SET , 437);
// message.setIntProperty(WMQConstants.JMS_IBM_ENCODING , 546);
message.setBooleanProperty(WMQConstants.WMQ_PERSISTENCE, Boolean.FALSE);
JMSProducer producer = context.createProducer();
// create Queue object
com.ibm.mq.jms.MQQueue q1 = new com.ibm.mq.jms.MQQueue();
q1.setBaseQueueManagerName("MYQUEUEMANAGERNAME");
q1.setBaseQueueName("MYINPUTQUEUENAME");
q1.setPersistence(DeliveryMode.NON_PERSISTENT);
q1.setTargetClient(JMSC.MQJMS_CLIENT_NONJMS_MQ); // Avoids RFH header!
// publish the message to queue
producer.send(q1, message);
logger.info("JMS message:\n" + message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在您的发件人应用程序调用MQDestination.setTargetClient
方法中使用 WMQConstants.WMQ_CLIENT_NONJMS_MQ
as 参数。这将确保RFH2
消息中不包含标头。
可用于 setTargetClient 方法的另一个值是MQJMS_CLIENT_JMS_COMPLIANT
。这表明该RFH2
格式用于发送信息。将 WebSphere MQ 类用于 JMS 的应用程序理解该RFH2
格式。MQJMS_CLIENT_JMS_COMPLIANT
当您与 JMS 应用程序的目标 WebSphere MQ 类交换信息时设置常量。
感谢您的回复。Stavr00 和 Shashi 的回答是正确的。虽然我通过使用 wmq 资源适配器修复了它。在资源适配器的配置中,我使用了
<config-property name="targetClient">MQ</config-property>
这相当于将 WMQConstants.WMQ_CLIENT_NONJMS_MQ 设置为队列。