ActiveMQ數據接收類型問題


一、問題描述

  最近開發了一個工具,功能是監聽ActiveMQ消息然后做相應的處理,本地自測沒有問題,但是部署在現場出現如下報錯:

[WARN ] [2020-08-27 19:49:42] [org.springframework.jms.listener.AbstractMessageListenerContainer.invokeErrorHandler(AbstractMessageListenerContainer.java:937)] Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method could not be invoked with incoming message
Endpoint handler details:
Method [public void com.hikvision.js.facecompare.service.impl.ConsumerListenerImpl.consumer(java.lang.String)]
Bean [com.hikvision.js.facecompare.service.impl.ConsumerListenerImpl@6c591143]
; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot convert from [java.util.HashMap] to [java.lang.String] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@2ebb7cc7, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@2ebb7cc7
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:118)
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:744)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:704)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674)
    at org.springframework.jms.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:645)
    at org.springframework.jms.listener.SimpleMessageListenerContainer.processMessage(SimpleMessageListenerContainer.java:322)
    at org.springframework.jms.listener.SimpleMessageListenerContainer.lambda$createListenerConsumer$2(SimpleMessageListenerContainer.java:299)
    at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1404)
    at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
    at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
    at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133)
    at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [java.util.HashMap] to [java.lang.String] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@2ebb7cc7, failedMessage=org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@2ebb7cc7
    at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144)
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109)
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114)
    ... 15 more

閱讀報錯很容易發現是數據類型轉換報錯Cannot convert from [java.util.HashMap] to [java.lang.String],於是猜測代碼希望我們使用map來接收,而我使用的是String,報錯代碼如下:

/**
     * 消息接收處理方法
     */
    @JmsListener(destination = "${activeMqTopic}", containerFactory = "topicListener")
    public void consumer(String message) {
        log.info("接收到一條消息:" + message);
        ...
}

二、解決方法

將數據接收類型修改為ActiveMQMapMessage,修改后代碼如下:

/**
     * 消息接收處理方法
     */
    @JmsListener(destination = "${activeMqTopic}", containerFactory = "topicListener")
    public void consumer(ActiveMQMapMessage message) throws Exception {
        log.info("接收到一條MQ消息");
        ...
    }

三、總結

  第一時間發現問題后,我將數據接收類型修改為Map,然后打包發給現場技術支持,技術支持重新部署后,稱還是報相同的錯,但實際使用Map接收也是可以的(估計是技術支持操作有問題)。

  ActiveMQ的5種消息類型:

  • TextMessage:java.lang.String對象,如xml文件內容。
  • MapMessage:key/value鍵值對的集合,key是String對象,值類型可以是Java任何基本類型。 
  • BytesMessage:字節流。
  • StreamMessage:Java 中的輸入輸出流。
  • ObjectMessage:Java中的可序列化對象。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM