如何删除 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 中的客户端标头?

如何根据客户端的验证错误添加和删除 CSS 类?

域如何通过脚本或策略实现删除客户端的启动项

如何修复来自 Apollo 客户端的格式错误的身份验证标头错误

如何从 weblogic JMS 队列集群环境中清除/删除消息

删除客户端的svn文件,不会将服务器里的文件也删除吧?