首页 > 解决方案 > 使用 spring 集成向非 jms 客户端发送消息

问题描述

我需要通过 IBM MQ 将消息从 spring 集成发送到非 jms 应用程序

我已尝试发送消息,但不幸的是,接收方非 jms 应用程序无法使用,因为消息中包含不需要的 Jms 标头并获取数据格式异常

如何在使用spring集成向非jms应用程序发送消息之前删除jms标头

我在 IBM MQ 站点中找到了一些参考链接

https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.dev.doc/q032140_.htm

标签: spring-integrationibm-mqspring-jms

解决方案


有很多方法可以做到这一点,从您已经收到的评论和答案的传播中可以看出。你如何做到这一点真的取决于你。

正如丹尼尔所说,您可以修改队列网址。

正如 Morag 所说,您可以使用 MQSC 来更改队列。

您也可以通过代码执行此操作。您没有提供任何代码,因此很难告诉您如何执行此操作,但如果您将目的地(队列)转换为 MQDestination,则可以使用 IBM JMS API 排除 RFH2 标头。

RFH2 将被排除在外

    import javax.jms.Destination;
    import com.ibm.mq.jms.MQDestination;
    import com.ibm.msg.client.wmq.WMQConstants;
    ...

    Destination destination = ...
    ...


    MQDestination mqDestination = (MQDestination) destination;
    destination.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);

我在春天用这个服务测试了这个


import com.ibm.mq.jms.MQDestination;
import com.ibm.msg.client.wmq.WMQConstants;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

import javax.jms.*;

@Service
public class SendMessageNonJmsService {

    protected final Log logger = LogFactory.getLog(getClass());

    final private JmsTemplate myNonJmsTemplate;

    @Autowired
    private ConnectionFactory connectionFactory;

    SendMessageNonJmsService(JmsTemplate myNonJmsTemplate) {
        this.myNonJmsTemplate = myNonJmsTemplate;
    }

    public void sendAsNonJms(String msg) {
        Destination destination = null;
        JMSContext context = connectionFactory.createContext();
        destination = context.createQueue("queue:///audit");
        try {
            MQDestination mqDestination = (MQDestination) destination;
            mqDestination.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);
        }
        catch (JMSException ex) {
            logger.warn("JMSException preparing message destination : "
                            + ex.getErrorCode() + " : "
                            + ex.getMessage());
        }
        myNonJmsTemplate.send(destination, session -> session.createTextMessage(msg));
    }

}

作为替代方案,如果您希望发送代码尽可能简单

    public void sendAsNonJms(String msg) {
        myNonJmsTemplate.send("audit", session -> session.createTextMessage(msg));
    }

然后你可以在你的 JmsTemplate 上设置一个目标解析器

    @Bean("myNonJmsTemplate")
    public JmsTemplate myNonJmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
        jmsTemplate.setDestinationResolver(new OurDestinationResolver());
        return jmsTemplate;
    }

您的目标解析器看起来像:

import com.ibm.mq.jms.MQDestination;
import com.ibm.msg.client.wmq.WMQConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.support.destination.DestinationResolver;

import javax.jms.*;

public class OurDestinationResolver implements DestinationResolver {

    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    private ConnectionFactory connectionFactory;

    @Override
    public Destination resolveDestinationName(Session session, String dest, boolean pubSub) throws JMSException {
        Destination destination = null;

        if (pubSub) {
            destination = session.createTopic(dest);
        } else {
            destination = session.createQueue(dest);
        }

        MQDestination mqDestination = (MQDestination) destination;
        mqDestination.setTargetClient(WMQConstants.WMQ_CLIENT_NONJMS_MQ);

        return destination;
    }
}

推荐阅读