如何删除 JMS 客户端的 RFH2 标头
Posted
技术标签:
【中文标题】如何删除 JMS 客户端的 RFH2 标头【英文标题】:How to remove RFH2 header for a JMS client 【发布时间】:2016-09-08 06:24:14 【问题描述】:我正在使用 JMS 客户端。该队列是一个 IBM MQ。当我在队列上写入数据时,它会添加 RFH 标头。如何剥离 RFH 标头。我无法使用 IBM MQ API。
【问题讨论】:
【参考方案1】:另一种方法是使用队列 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 MQ 侦听器端,我还是使用 spring boot from("direct:request")。设置属性(“TARGCLIENT”,常量(“1”))。 setHeader("JMS_IBM_Character_Set", 常量("UTF-8")).【参考方案2】:从 IBM WebSphere MQ v7 开始,告诉 Java 实现不生成 MQRFH2 标头的推荐方法是调用 MQDestination.setMessageBodyStyle( WMQConstants.WMQ_MESSAGE_BODY_MQ)
,因为 TARGCLIENT
属性仅在 MessageBodyStyle
显式设置为 @987654324 时用作备用选项@。
【讨论】:
【参考方案3】:使用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
,这将去除标题,但根据我的经验,最好通过应用程序配置来做到这一点。
【讨论】:
【参考方案4】:在您的发件人应用程序中调用MQDestination.setTargetClient
方法,并将WMQConstants.WMQ_CLIENT_NONJMS_MQ
作为参数。这将确保RFH2
标头不包含在消息中。
可用于 setTargetClient 方法的另一个值是MQJMS_CLIENT_JMS_COMPLIANT
。这表明RFH2
格式用于发送信息。将 WebSphere MQ 类用于 JMS 的应用程序理解 RFH2
格式。在与 JMS 应用程序的目标 WebSphere MQ 类交换信息时设置 MQJMS_CLIENT_JMS_COMPLIANT
常量。
【讨论】:
【参考方案5】:由于访问此页面的一些读者实际上可以使用 IBM API,以下是我的代码,用于为不支持 RFH 标头的旧客户端发布 IBM MQ v8 的消息。
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();
【讨论】:
【参考方案6】:感谢您的回复。 Stavr00 和 Shashi 的回答是正确的。 虽然我通过使用 wmq 资源适配器修复了它。在资源适配器的配置中,我使用了
<config-property name="targetClient">MQ</config-property>
这相当于将 WMQConstants.WMQ_CLIENT_NONJMS_MQ 设置为队列。
【讨论】:
以上是关于如何删除 JMS 客户端的 RFH2 标头的主要内容,如果未能解决你的问题,请参考以下文章
如何在将请求传递给上游服务器之前删除 Nginx 中的客户端标头?
如何修复来自 Apollo 客户端的格式错误的身份验证标头错误