为什么 Jackson2JsonMessageConverter 将 List<String> 转换为 List<Object>

Why Jackson2JsonMessageConverter convert List<String> to List<Object>

我正在使用 RabbitMQ 开发 Spring AMQP,我配置了 MessageConverter( Jackson2JsonMessageConverter)ObjectMapper。如果我通过传递 HashMap<String,Object> 从发件人 class 调用 convertAndSend(,,,) 方法,那么 Receiver class handleMessage() 方法成功获得类型 [=22= 的消息] 。但问题是,这个 HashMap 包含一个 List 的字符串作为 List<String> 。当我在 Receiver 中收到此 HashMap 时,我试图通过密钥获取 List<String> 但它给出了错误 List<Object> can't cast Object list to string list 。这是我的代码 Config class ,发送者 class 和接收者 class

@Configuration
public class RabbitMQConfig {

    @Autowired
    Environment environment;

    final static String paymentQueue = "mobily-payment-queue";
    final static String mailQueue = "mobily-mail-queue";
    final static String orderQueue = "mobily-order-queue";
    final static String deductProductQueue = "mobily-deduct-product-queue";
    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(environment.getRequiredProperty("rabbitmq.host"),Integer.parseInt(environment.getRequiredProperty("rabbitmq.port")));
        connectionFactory.setUsername(environment.getRequiredProperty("rabbitmq.user"));
        connectionFactory.setPassword(environment.getRequiredProperty("rabbitmq.pass"));
        return connectionFactory;
    }

    @Bean 
    public MessageConverter jsonMessageConverter() { 
        final Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(); 


        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JodaModule());
        mapper.registerModule(new Hibernate4Module());
        mapper.setSerializationInclusion(Include.NON_NULL);
         converter.setJsonObjectMapper(mapper);
        return converter; 
     }


    @Bean
    public RabbitTemplate template(MessageConverter jsonMessageConverter) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        template.setMessageConverter(jsonMessageConverter);
        return template;
    }

    @Bean
    public DirectExchange direct() {
        return new DirectExchange("mobily.direct");
    }

        @Bean
        public Queue paymentQueue(){
            return new Queue(paymentQueue);
        }

        @Bean
        public Queue deductProductQueue() {
            return new Queue(deductProductQueue);
        }

        @Bean
        public Queue orderQueue() {
            return new Queue(orderQueue);
        }

        @Bean
        public Queue mailQueue(){
            return new Queue(mailQueue);
        }

        @Bean
        public Binding paymentBinding(DirectExchange direct, Queue paymentQueue) {
            return BindingBuilder.bind(paymentQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.payment.key"));
        }

        @Bean
        public Binding deductProductBinding(DirectExchange direct, Queue deductProductQueue) {
            return BindingBuilder.bind(deductProductQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.deduct.product.key"));
        }

        @Bean
        public Binding orderBinding(DirectExchange direct, Queue orderQueue) {
            return BindingBuilder.bind(orderQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.order.key"));
        }

        @Bean
        public Binding mailBinding(DirectExchange direct, Queue mailQueue) {
            return BindingBuilder.bind(mailQueue).to(direct).with(environment.getRequiredProperty("rabbitmq.mail.key"));
        }

        /*@Bean
        Receiver receiver() {
            return new Receiver();
        }*/

        @Bean
        PaymentReceiver paymentReceiver(){

            return new PaymentReceiver();
        }

        @Bean
        DeductProductReceiver deductProductReceiver(){

            return new DeductProductReceiver();
        }

        @Bean
        OrderReceiver orderReceiver(){
            return new OrderReceiver();
        }

        @Bean
        MailReceiver mailReceiver(){

            return new MailReceiver();
        }

        @Bean
        SimpleMessageListenerContainer deductProductContainer(ConnectionFactory connectionFactory, MessageListenerAdapter deductProductListenerAdapter) {
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.setQueueNames(deductProductQueue);
            container.setMessageListener(deductProductListenerAdapter);
            return container;


        }

        @Bean
        MessageListenerAdapter deductProductListenerAdapter(DeductProductReceiver deductProductReceiver,MessageConverter jsonMessageConverter) {
            return new MessageListenerAdapter(deductProductReceiver, jsonMessageConverter);
        }

        @Bean
        SimpleMessageListenerContainer paymentContainer(ConnectionFactory connectionFactory, MessageListenerAdapter paymentListenerAdapter) {
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.setQueueNames(paymentQueue);
            container.setMessageListener(paymentListenerAdapter);
            return container;


        }

        @Bean
        MessageListenerAdapter paymentListenerAdapter(PaymentReceiver paymentReceiver,MessageConverter jsonMessageConverter) {
            return new MessageListenerAdapter(paymentReceiver,jsonMessageConverter );
        }

        @Bean
        SimpleMessageListenerContainer orderContainer(ConnectionFactory connectionFactory, MessageListenerAdapter orderListenerAdapter) {
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.setQueueNames(orderQueue);
            container.setMessageListener(orderListenerAdapter);
            return container;


        }

        @Bean
        MessageListenerAdapter orderListenerAdapter(OrderReceiver orderReceiver,MessageConverter jsonMessageConverter) {
            return new MessageListenerAdapter(orderReceiver,jsonMessageConverter);
        }

        @Bean
        SimpleMessageListenerContainer mailContainer(ConnectionFactory connectionFactory, MessageListenerAdapter mailListenerAdapter) {
            SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
            container.setConnectionFactory(connectionFactory);
            container.setQueueNames(mailQueue);
            container.setMessageListener(mailListenerAdapter);
            return container;


        }

        @Bean
        MessageListenerAdapter mailListenerAdapter(MailReceiver mailReceiver,MessageConverter jsonMessageConverter) {
            return new MessageListenerAdapter(mailReceiver,jsonMessageConverter);
        }




}

这是我的发件人class

HashMap<String, Object> mailMap=new HashMap<String, Object>();
CustomerAccountUser customerAccountUser=customerAccountUserService.getCustomerAccountUserByUsername(customerAccountPayments.getCustomerName());
             ArrayList<String> emailAddress=new ArrayList<String>();
             emailAddress.add(customerAccountUser.getEmail());
 template.convertAndSend(direct.getName(),environment.getRequiredProperty("rabbitmq.mail.key"),mailMap);

这是我的接收器

public void handleMessage(HashMap<String,Object> mailMap){

    try{
        System.out.println("mail queue..................................." + mailMap);
        String s1=(String)mailMap.get("subject");
        String s2=(String)mailMap.get("body");
        List<String> list=(List<String>)mailMap.get("emailAddress");
    }
}

这是错误

    e2016-05-24 17:02:47 ERROR stderr:71 - java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
2016-05-24 17:02:47 ERROR stderr:71 -   at com.mobily.service.EmailService.sendEmail(EmailService.java:24)
2016-05-24 17:02:47 INFO  stdout:71 -     values
2016-05-24 17:02:47 ERROR stderr:71 -   at com.mobily.customer.rabbitmq.reciever.MailReceiver.handleMessage(MailReceiver.java:27)
2016-05-24 17:02:47 ERROR stderr:71 -   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2016-05-24 17:02:47 ERROR stderr:71 -   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2016-05-24 17:02:47 ERROR stderr:71 -   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2016-05-24 17:02:47 ERROR stderr:71 -   at java.lang.reflect.Method.invoke(Method.java:497)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:387)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:298)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:757)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:680)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access[=15=]1(SimpleMessageListenerContainer.java:93)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:183)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1358)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:661)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1102)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1086)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access00(SimpleMessageListenerContainer.java:93)
2016-05-24 17:02:47 ERROR stderr:71 -   at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1203)`enter code here`e

嗯,很遗憾 Jackson2JsonMessageConverter 不能为你做那件事。

它的逻辑基于三个消息 headers:

public static final String DEFAULT_CLASSID_FIELD_NAME = "__TypeId__";

public static final String DEFAULT_CONTENT_CLASSID_FIELD_NAME = "__ContentTypeId__";

public static final String DEFAULT_KEY_CLASSID_FIELD_NAME = "__KeyTypeId__";

所以,它能做的最好的事情就是 HashMap<Foo, Bar>。但它无法构建正确的嵌套容器类型,因为消息中没有这样的信息 headers.

当然,您必须在 handleMessage 代码的下游做一些进一步的转换(转换)逻辑。我的意思是不转换为 List<String>,而是迭代并转换每个项目。

虽然按照你的发送逻辑:

ArrayList<String> emailAddress=new ArrayList<String>();
emailAddress.add(customerAccountUser.getEmail());

您可以尝试使用 array (String[]) 而不是 List<String>。这应该可以正常工作,因为数组被视为原始类型,而不是容器。