Apache camel 如何使用Apache Camel浏览队列中的消息?

Apache camel 如何使用Apache Camel浏览队列中的消息?,apache-camel,Apache Camel,我需要使用驼峰路由浏览来自活动mq的消息,而不使用这些消息 JMS队列中的消息将被读取(仅浏览而不使用)并移动到数据库中,同时确保原始队列保持完整 public class CamelStarter { private static CamelContext camelContext; public static void main(String[] args) throws Exception { cam

我需要使用驼峰路由浏览来自活动mq的消息,而不使用这些消息

JMS队列中的消息将被读取(仅浏览而不使用)并移动到数据库中,同时确保原始队列保持完整

public class CamelStarter {

   private static CamelContext camelContext;

            public static void main(String[] args) throws Exception {
                            camelContext = new DefaultCamelContext();
                            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

                            camelContext.addComponent("jms",  JmsComponent.jmsComponent(connectionFactory));

                            camelContext.addRoutes(new RouteBuilder() {

                                            @Override
                                            public void configure() throws Exception {
                                                from("jms:queue:testQueue").to("browse:orderReceived") .to("jms:queue:testQueue1");
                                            }

                                            }
                            );

                            camelContext.start();

                            Thread.sleep(1000);

                             inspectReceivedOrders();

                            camelContext.stop();

            }
公共静态无效检查接收器(){

BrowsableEndpoint browse=camelContext.getEndpoint(“浏览:orderReceived”,BrowsableEndpoint.class);
列表交换=browse.getExchanges();
System.out.println(“浏览队列:+browse.getEndpointUri()+”大小:+exchanges.size());
用于(交换:交换){
字符串负载=exchange.getIn().getBody(String.class);
字符串msgId=exchange.getIn().getHeader(“JMSMessageID”,String.class);
System.out.println(msgId+“=”+有效载荷);

}

Apache camel browse组件正是为此而设计的。请查看文档

因为您没有提供任何其他信息,所以不能再多说了

假设你有这样的路线

from("activemq:somequeue).to("bean:someBean")  
from("activemq:somequeue).to("browse:someHandler").to("bean:someBean")   

你所要做的就是像这样在两者之间放置一个浏览端点

from("activemq:somequeue).to("bean:someBean")  
from("activemq:somequeue).to("browse:someHandler").to("bean:someBean")   
然后写一个这样的类

@Component
public class BrowseQueue {

  @Autowired
  CamelContext camelContext;

  public void inspect() {
    BrowsableEndpoint browse = camelContext.getEndpoint("browse:someHandler", BrowsableEndpoint.class);
    List<Exchange> exchanges = browse.getExchanges();


    for (Exchange exchange : exchanges) {
      ...... 
    }
  }

}
@组件
公共类浏览器{
@自动连线
CamelContext和CamelContext;
公共空间检查(){
BrowsableEndpoint browse=camelContext.getEndpoint(“browse:someHandler”,BrowsableEndpoint.class);
列表交换=browse.getExchanges();
用于(交换:交换){
...... 
}
}
}

据我所知,在Camel中无法读取(不使用!)JMS消息:-( 我发现(在JEE应用程序中)唯一的解决方法是定义一个带有计时器的启动EJB,持有QueueBrowser,并将msg处理委托给驼峰路由:

@Singleton
@Startup
public class MyQueueBrowser  {

    private TimerService timerService;

    @Resource(mappedName="java:/jms/queue/com.company.myqueue")
    private Queue sourceQueue;

    @Inject
    @JMSConnectionFactory("java:/ConnectionFactory")
    private JMSContext jmsContext;  

    @Inject
    @Uri("direct:readMessage")
    private ProducerTemplate camelEndpoint;


    @PostConstruct
    private void init() {       
        TimerConfig timerConfig = new TimerConfig(null, false);
        ScheduleExpression se = new ScheduleExpression().hour("*").minute("*/"+frequencyInMin);
        timerService.createCalendarTimer(se, timerConfig);
    }


    @Timeout
    public void scheduledExecution(Timer timer) throws Exception {      
        QueueBrowser browser = null;
        try {                       
            browser = jmsContext.createBrowser(sourceQueue);                                           
            Enumeration<Message> msgs = browser.getEnumeration();
            while ( msgs.hasMoreElements() ) { 
                Message jmsMsg = msgs.nextElement(); 
                // + here: read body and/or properties of jmsMsg                                            
                camelEndpoint.sendBodyAndHeader(body, myHeaderName, myHeaderValue);
            }                                                                               
        } catch (JMSRuntimeException jmsException) {
            ...
        } finally {        
            browser.close();
        }
    }


}
@Singleton
@启动
公共类MyQueueBrowser{
私人TimerService TimerService;
@资源(mappedName=“java:/jms/queue/com.company.myqueue”)
专用队列源队列;
@注入
@JMSConnectionFactory(“java:/ConnectionFactory”)
私有JMSContext JMSContext;
@注入
@Uri(“direct:readMessage”)
私营生产企业;
@施工后
私有void init(){
TimerConfig TimerConfig=新的TimerConfig(null,false);
ScheduleExpression se=新的ScheduleExpression().hour(“*”).minute(“*/”+frequencyInMin);
timerService.createCalendarTimer(se,timerConfig);
}
@超时
public void scheduledExecution(计时器)引发异常{
QueueBrowser=null;
试试{
browser=jmsContext.createBrowser(sourceQueue);
枚举msgs=browser.getEnumeration();
而(msgs.hasMoreElements()){
消息jmsmssg=msgs.nextElement();
//+此处:读取jmsMsg的正文和/或属性
cameleEndpoint.sendBodyAndHeader(主体、myHeaderName、myHeaderValue);
}                                                                               
}捕获(JMSRuntimeException JMSExException){
...
}最后{
browser.close();
}
}
}

我尝试过这样做,但没有成功。请阅读更新的问题描述。此代码片段正在创建两个队列之间交换的副本。但是,队列中的消息在阅读时丢失。谁应该使用队列中的消息,消费者如何使用?您能显示您拥有的路线吗什么是jms:queue:testQueue1?您在inspectOrders中做什么?需要解释吗?jms:queue:testQueue1:它是活动mq中的队列名称