如何使用 Apache Camel 从 Java 类访问 JMS 队列?

Posted

技术标签:

【中文标题】如何使用 Apache Camel 从 Java 类访问 JMS 队列?【英文标题】:How can I access a JMS queue from a Java class using Apache Camel? 【发布时间】:2021-05-15 10:49:17 【问题描述】:

我有一个 Apache Camel 中间件来在两个系统之间同步实体。如果实体到达目的地时发生错误,我会在 JMS 队列中存储一条消息,其中包含有关该错误的信息。

我们在 Camel 内部还有一个 API 可以“查询”该队列。上述 API 的 GET 方法之一应将所有消息放入错误队列中,并为队列中的每条消息使用 EntityId + 错误消息形成响应。

我知道我可以使用类似这样的方式从队列中消费(我正在使用 Spring Boot):

@Autowired
private ConsumerTemplate consumTemplate;

然后从ConsumerTemplate 调用receive,但这似乎不是一个非常合适的方法,因为我怎么知道什么时候没有更多消息?我可以等待null,但我只是想知道是否有更优雅的方式来做到这一点。

所以我的问题是:有什么方法可以将队列中的所有消息都放入List 或类似的东西中,而不是一个一个地使用它们?而且我还不需要“消费”它们,而是浏览它们,因此所有消息都保留在队列中以供进一步处理。

我尝试过这样的事情:

@Autowired
private JmsComponent jms;

public void getAllErrorGroups() throws Exception 
    javax.jms.Session jmsSession = jms.getConnectionFactory().createConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
    QueueBrowser browser = jmsSession.createBrowser(jmsSession.createQueue(ApplicationConstants.Routes.ERROR _QUEUE_ROUTE));        
    Enumeration<?> enumeration = browser.getEnumeration();

但我在enumeration 上一无所获。我在调试器中查看了它,还做了一个while(enumeration.hasNext()),它从未进入while循环。

【问题讨论】:

将所有消息从队列中获取到列表或类似的东西中。而不是一一消费消息。我可以等待一个空值,我只是想知道是否有更优雅的方式来做到这一点。 哦,好的。感谢您的宝贵时间 =) 【参考方案1】:

JMS API 不支持一次接收多于一条消息的功能,因此您必须逐条处理。此外,我不知道有什么比超时调用receive(long) 并获取null 更优雅的方法来确定队列为空。

至于您的浏览器,我相信您没有得到任何东西,因为您没有在 JMS 连接上调用 start()。试试这样的:

@Autowired
private JmsComponent jms;

public void getAllErrorGroups() throws Exception 
   javax.jms.Connection jmsConnection = jms.getConnectionFactory().createConnection();
   javax.jms.Session jmsSession = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   jmsConnection.start();

   QueueBrowser browser = jmsSession.createBrowser(jmsSession.createQueue(ApplicationConstants.Routes.ERROR _QUEUE_ROUTE));
    
   Enumeration<?> enumeration = browser.getEnumeration();

【讨论】:

可悲的是它仍然是空的:( 我查看了调试器,也做了一段时间(enumeration.hasNext()) 并没有进入那个时间。 你确认对应的JMS队列里面有消息了吗?如果有,怎么做? 在我的测试用例中,我在调用 getAllErrorGroups() 函数之前向队列发送了一条消息。我还可以在 ActiveMQ UI 上看到该错误。 您确定ApplicationConstants.Routes.ERROR _QUEUE_ROUTE 指的是代理的正确队列吗?如果在 browser 上调用 getEnumeration 时在调试器中停止应用程序,ActiveMQ Web 控制台会显示您的客户端吗?

以上是关于如何使用 Apache Camel 从 Java 类访问 JMS 队列?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决 java.lang.NoClassDefFoundError: org/apache/camel/impl/DefaultComponent?

如何读取HL7文件并使用Apache Camel,Hapi和Spring(Java配置)解析它

如何调查 Apache Camel Route 上的数据?

如何在apache camel 2.23.1版本的处理器交换对象中获取RouteId?

如何在 Apache Camel 中检测损坏/恢复的 JMS 连接?

Payara中的Apache Camel:'java:/ TransactionManager'查找失败