Solace JMS队列接收JSON消息失败排查:队列已存在警告及无消息问题
Solace JMS队列无法接收JSON消息且提示队列已存在的问题排查与解决
先来说说你遇到的两个问题:队列已存在的警告,以及无法接收消息,咱们一步步拆解解决。
一、关于“Response - 400 Queue already exists”警告的原因与解决
你代码里设置了connectionFactory.setDynamicDurables(true);,这个配置的作用是让客户端在队列不存在时自动动态创建队列。但现在你要连接的test.Request.Q.V01队列已经在Solace Broker上存在了,客户端尝试动态创建一个同名队列,就会触发这个400错误警告。
解决方法很简单:
- 既然队列已经预先在Broker上创建好了,直接移除
connectionFactory.setDynamicDurables(true);这行代码即可。客户端会直接使用已存在的队列,不会再尝试创建,警告自然消失。 - 如果你确实需要动态创建(不推荐,因为队列已经存在),需要确保Broker上的队列配置允许“动态覆盖”,但这种场景很少见,优先推荐第一种方案。
二、无法接收JSON消息的可能原因与修复
你的代码里有几个关键问题导致收不到消息(或者收到了但没正确识别),咱们逐一修正:
1. 错误的消息类型判断
你在监听器里判断message instanceof SolaceMsg,这是个误区——Solace发送的JSON消息通常是以**TextMessage**(文本消息)的形式传递的,SolaceMsg是Solace内部的底层消息类型,一般不会直接暴露给JMS客户端。
修正代码里的消息处理逻辑,改成识别TextMessage,然后解析JSON内容:
messageConsumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { try { if (message instanceof TextMessage) { // 提取JSON文本内容 TextMessage textMsg = (TextMessage) message; String jsonContent = textMsg.getText(); System.out.printf("Received JSON message content:%n%s%n", jsonContent); // 解析成你的POJO(假设你有对应的外层类和CustomerDetails类) ObjectMapper mapper = new ObjectMapper(); YourPojoClass pojo = mapper.readValue(jsonContent, YourPojoClass.class); System.out.printf("Parsed Customer ID: %s, Name: %s%n", pojo.getCustomerDetails().getCustomerID(), pojo.getCustomerDetails().getCustomerName()); } else { System.out.println("Received non-text message, dump content:"); System.out.println(SolJmsUtility.dumpMessage(message)); } message.acknowledge(); latch.countDown(); } catch (JMSException | JsonProcessingException ex) { System.err.println("Error processing incoming message:"); ex.printStackTrace(); } } });
2. 权限与队列验证
- 确认你的用户名
testVpn在TEST_VPN里拥有对test.Request.Q.V01队列的读取权限(消费权限)。可以通过Solace的管理控制台检查队列的权限配置。 - 验证消息是否真的发送到了这个队列:登录Solace管理控制台,查看该队列的“消息计数”,确认是否有消息堆积或进入队列。如果队列里没有消息,那问题出在发送端,不是消费端。
3. 确认模式的小细节
你用了SupportedProperty.SOL_CLIENT_ACKNOWLEDGE作为会话的确认模式,这个是Solace的扩展属性,虽然没问题,但也可以换成标准JMS的Session.CLIENT_ACKNOWLEDGE,兼容性更好:
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
三、其他需要检查的点
- 确认连接参数(host、VPN、用户名密码)完全正确,代码里打印的连接成功日志只是说明客户端连上了Broker,不代表VPN和队列的权限没问题。
- 如果你的程序需要接收多条消息,当前的
CountDownLatch(1)会在收到一条消息后就退出,这会导致后续消息无法接收。如果是测试用例没问题,但生产环境需要调整逻辑。
按照上面的步骤修改后,应该就能解决警告和收不到消息的问题了。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

