JMS监听MQSeries报错:无法确定响应目标,无回复目标
问题描述
控制台反复出现以下错误:
jakarta.jms.InvalidDestinationException: Cannot determine response destination: Request message does not contain reply-to destination, and no default response destination set.
从MQSeries接收消息后,应用持续运行并不断输出该错误及相同的消息内容。
相关代码
@RestController @Service @EnableJms public class MQReceiver { private static final Logger LOGGER = LoggerFactory.getLogger(MQReceiver.class.getName()); @JmsListener(destination = "${ibm.mq.additionalProperties.queue1}") protected String receiveMessage(@Payload String message, @Header(JmsHeaders.MESSAGE_ID) String messageId) throws IOException, Throwable{ BufferedWriter bw; FileWriter fw; LOGGER.info("received OrderNumber='{}' with MessageId='{}'", message, messageId); return "Le message est : " + message; } }
期望效果:控制台仅输出一次消息且无错误。
问题原因
当@JmsListener注解的方法有返回值时,Spring JMS会自动尝试将返回值作为响应消息发送至回复目的地。这个回复目的地的来源有两个:
- 接收的消息中自带的
reply-to头部信息 - 配置的默认回复目的地
如果两者都未提供,就会抛出上述异常。同时,由于消息处理失败,MQ会将消息重新放回队列,导致应用反复接收同一条消息,重复触发错误。
解决方案
根据实际需求选择以下方案:
方案1:不需要返回响应消息
将方法返回类型改为void,Spring JMS就不会尝试发送响应,自然不会触发错误:
@RestController @Service @EnableJms public class MQReceiver { private static final Logger LOGGER = LoggerFactory.getLogger(MQReceiver.class.getName()); @JmsListener(destination = "${ibm.mq.additionalProperties.queue1}") protected void receiveMessage(@Payload String message, @Header(JmsHeaders.MESSAGE_ID) String messageId) throws IOException, Throwable{ BufferedWriter bw; FileWriter fw; LOGGER.info("received OrderNumber='{}' with MessageId='{}'", message, messageId); // 保留原有业务逻辑,无需返回值 } }
方案2:需要返回响应消息
如果确实需要发送响应,二选一即可:
- 方式A:确保发送到队列的消息包含
reply-to头部,指定响应要发送的目标队列。 - 方式B:在
@JmsListener注解中通过replyDestination属性配置默认回复目的地(需确保该队列已在IBM MQ中创建并配置正确):
@JmsListener(destination = "${ibm.mq.additionalProperties.queue1}", replyDestination = "${ibm.mq.additionalProperties.replyQueue}") protected String receiveMessage(@Payload String message, @Header(JmsHeaders.MESSAGE_ID) String messageId) throws IOException, Throwable{ LOGGER.info("received OrderNumber='{}' with MessageId='{}'", message, messageId); return "Le message est : " + message; }
额外注意
解决异常后,消息会被正常确认,不会再被MQ重复投递,控制台也只会输出一次消息日志。
内容的提问来源于stack exchange,提问作者Hamzix91
相关产品推荐
相关产品推荐

