如何在Spring Boot中向IBM-MQ发送带MQIIH头的JMS消息?
解决IBM MQ发送IIH头消息却出现RFH2头的问题
问题原因
你之前的代码把IIH的字段当作JMS消息属性来设置,而IBM MQ JMS客户端默认会将所有JMS属性封装到RFH2头中,所以不管怎么设置StrucId,最终都会带上RFH2头,而非预期的IIH头。
解决方案
要发送带IIH头的消息,需要直接操作IBM MQ原生API构造IIH头,同时配置JMS客户端禁用RFH2头的自动添加:
1. 配置JmsTemplate,禁用RFH2头
修改JmsTemplate的配置,设置targetClient为WMQ_CLIENT_NONJMS_MQ,让客户端按原生MQ消息格式发送:
@Bean public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) { JmsTemplate template = new JmsTemplate(connectionFactory); template.setTargetClient(MQJMSConstants.WMQ_CLIENT_NONJMS_MQ); return template; }
2. 重构发送代码,直接构造IIH头
使用IBM MQ的MQIIH类创建IIH头,写入原生MQMessage,再转换为JMS消息发送:
public void send(Request mqRequest) throws JMSException, IOException { log.info("sending with message [{}] to queue [{}].", mqRequest.getMessage(), QUEUE_NAME); // 创建MQ原生消息并写入消息体 MQMessage mqMessage = new MQMessage(); mqMessage.writeString(mqRequest.getMessage()); // 构造IIH头并设置对应字段 MQIIH iih = new MQIIH(); iih.setStrucId(MQIIH.MQIIH_STRUC_ID); iih.setStrucLength(MQIIH.MQIIH_STRUC_LENGTH_VERSION_1); iih.setVersion(MQIIH.MQIIH_VERSION_1); iih.setAuthenticator("********"); iih.setFormat("********"); iih.setReplyToFormat("********"); iih.setCommitMode('0'); iih.setLTermOverride("********"); iih.setMFSMapName("********"); iih.setSecurityScope('C'); // 将IIH头写入MQ消息头部 iih.write(mqMessage); // 通过JmsTemplate发送消息 jmsTemplate.send(QUEUE_NAME, session -> { MQJmsTextMessage jmsMessage = (MQJmsTextMessage) session.createTextMessage(); // 设置必要的JMS头部 jmsMessage.setJMSCorrelationID(UUID.randomUUID().toString()); jmsMessage.setJMSType("MQIIH"); // 关联原生MQ消息(包含IIH头和消息体) jmsMessage.setMQMessage(mqMessage); return jmsMessage; }); }
关键说明
- 不要通过JMS消息的
setProperty方法设置IIH字段,这些属性会被客户端自动打包到RFH2头中。 WMQ_CLIENT_NONJMS_MQ参数会让客户端以原生MQ协议发送消息,避免添加RFH2头。- 直接使用
MQIIH类构造头并写入原生消息,才能确保消息携带正确的IIH头。
内容的提问来源于stack exchange,提问作者Javanectar
相关产品推荐
相关产品推荐

