【问题标题】:Unable to read object content Spring Boot activemqSpring Boot activemq 无法读取对象内容
【发布时间】:2018-08-01 16:14:55
【问题描述】:

我正在尝试使用 Spring Boot 和 Active MQ 在消费者端使用 POJO。收到消息但无法转换为对象的实际类型,以下异常:

例外:

2018-08-01 10:51:35.542  INFO 9280 --- [enerContainer-1] com.example.JmsConsumer                  : Message reached in consumer side...
2018-08-01 10:51:35.542  INFO 9280 --- [enerContainer-1] com.example.JmsConsumer                  : +++++++++++++++++++++++++++++++++++++++++++++++++++++
2018-08-01 10:51:35.547  WARN 9280 --- [enerContainer-1] o.s.j.l.DefaultMessageListenerContainer  : Execution of JMS message listener failed, and no ErrorHandler has been set.

java.lang.AbstractMethodError: org.apache.activemq.command.ActiveMQObjectMessage.getBody(Ljava/lang/Class;)Ljava/lang/Object;
    at com.example.JmsConsumer.receive(JmsConsumer.java:49) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]

POJO:

public class OrderDetails implements Serializable{
    private Long id;
    private String name;
    private double itemPrice;
    private double totalPrice;
    private String orderStatus;

}

发布方:

import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;

import com.example.model.OrderDetails;
    @Component
    public class JmsProducer  {

        @Autowired
        JmsTemplate jmsTemplate;

        @Value("${jsa.activemq.queue}")
        String queueName;

        public void send(OrderDetails msg) {
            this.jmsTemplate.convertAndSend(queueName, msg);
    }

消费者方面:

import javax.jms.JMSException;
import javax.jms.Message;
import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RestTemplate;

    import com.example.model.OrderDetails;
    import com.fasterxml.jackson.databind.ObjectMapper;

    import lombok.extern.slf4j.Slf4j;

        @Component
        @Slf4j
        public class JmsConsumer {

  @JmsListener(destination = "${jsa.activemq.queue}", containerFactory="jsaFactory")
       public void receive(Message message) throws JMSException{
                log.info("Message reached in consumer side...");
                    log.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++");
          OrderDetails response = Message.getBody(OrderDetails.class);
       log.info("Application : object received : {}",response);
            }
      }

活动 MQ 配置:

import javax.jms.ConnectionFactory;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@Value("${jsa.activemq.broker.url}")
    String brokerUrl;

    @Value("${jsa.activemq.borker.username}")
    String userName;

    @Value("${jsa.activemq.borker.password}")
    String password;

    /*
     * Initial ConnectionFactory
     */
    @Bean
    public ConnectionFactory connectionFactory(){
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(brokerUrl);
        connectionFactory.setUserName(userName);
        connectionFactory.setPassword(password);
        connectionFactory.setTrustAllPackages(true);
        return connectionFactory;
    }

    @Bean // Serialize message content to json using TextMessage
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.OBJECT);
        converter.setTypeIdPropertyName("id");
        return converter;
    }

    /*
     * Used for Receiving Message
     */
    @Bean
    public JmsListenerContainerFactory<?> jsaFactory(ConnectionFactory connectionFactory,
                                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setMessageConverter(jacksonJmsMessageConverter());
        configurer.configure(factory, connectionFactory);
        return factory;
    }

        /*
     * Used for Sending Messages.
     */
    @Bean
    public JmsTemplate jmsTemplate(){
        JmsTemplate template = new JmsTemplate();
        template.setConnectionFactory(connectionFactory());
        return template;
    }

Active MQ 配置在 Publisher 和 Listener 端是相同的。我已经注册了消息转换器,但我不确定为什么从 JSON 到对象的转换不起作用。任何解决此问题的指针表示赞赏。

【问题讨论】:

    标签: spring spring-boot activemq spring-jms


    【解决方案1】:

    我认为你的 jar 有问题。我认为可能是你使用的一些旧版本的 jar。请检查你的 jar 版本和你使用的 JDK

    【讨论】:

    • 我正在使用 JDK 10 和最新版本的活动 mq(5.15.4)。如果 jar 是一个问题,那么发布部分是如何工作的?
    【解决方案2】:

    我通过直接使用 POJO 而不是将其作为 javax.jms.Message 使用来解决此错误。消息转换器 Bean 也应初始化如下:

    // 使用TextMessage将消息内容序列化为json

    @Bean
    public MessageConverter jacksonJmsMessageConverter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }
    

    请在 github 中查看我的代码:

    https://github.com/sureshpec04/spring-boot-jms

    【讨论】:

      猜你喜欢
      • 2018-01-31
      • 1970-01-01
      • 2021-09-07
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      相关资源
      最近更新 更多