使用兔子监听器的Spring amqp转换器问题

use*_*718 9 rabbitmq spring-rabbit spring-amqp spring-rabbitmq

我想我在这里遗漏了一些东西......我正在尝试创建简单的兔子列表器,它可以接受自定义对象作为消息类型.现在按照医生的说法

在1.6之前的版本中,转换JSON的类型信息必须在消息头中提供,或者需要自定义ClassMapper.从版本1.6开始,如果没有类型信息头,则可以从目标方法参数推断出类型.

我在仪表板中使用rabbit mq adm手动将消息放入队列,得到错误

Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [com.example.Customer] for GenericMessage [payload=byte[21], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=customer, amqp_deliveryTag=1, amqp_consumerQueue=customer, amqp_redelivered=false, id=81e8a562-71aa-b430-df03-f60e6a37c5dc, amqp_consumerTag=amq.ctag-LQARUDrR6sUcn7FqAKKVDA, timestamp=1485635555742}]
Run Code Online (Sandbox Code Playgroud)

我的配置:

@Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new    CachingConnectionFactory("localhost");
        connectionFactory.setUsername("test");
        connectionFactory.setPassword("test1234");
        connectionFactory.setVirtualHost("/");
        return connectionFactory;
    }

    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public AmqpAdmin amqpAdmin() {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());
        return rabbitAdmin;
    }

    @Bean
    public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
Run Code Online (Sandbox Code Playgroud)

还有问题是这个异常消息没有放回队列中.

我使用的是spring boot 1.4,它带来了amqp 1.6.1.

编辑1:我添加了如上所述的jackson转换器(弹簧启动时不需要)并在rmq admin上给出了内容类型,但仍然在下面,如上所示,我还没有配置任何监听器容器.

Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [com.example.Customer] for GenericMessage [payload=byte[21], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=customer, content_type=application/json, amqp_deliveryTag=3, amqp_consumerQueue=customer, amqp_redelivered=false, id=7f84d49d-037a-9ea3-e936-ed5552d9f535, amqp_consumerTag=amq.ctag-YSemzbIW6Q8JGYUS70WWtA, timestamp=1485643437271}]
Run Code Online (Sandbox Code Playgroud)

Gar*_*ell 18

如果你正在使用启动,你可以简单地添加一个Jackson2JsonMessageConverter @Bean配置,它将自动连接到监听器(只要它是唯一的转换器).如果使用管理控制台发送消息content_type,application/json则需要将属性设置为 .

转换错误默认为致命,因为通常没有理由重试; 否则他们会永远地循环.

编辑

这是一个有效的启动应用程序......

@SpringBootApplication
public class So41914665Application {

    public static void main(String[] args) {
        SpringApplication.run(So41914665Application.class, args);
    }

    @Bean
    public Queue queue() {
        return new Queue("foo", false, false, true);
    }

    @Bean
    public Jackson2JsonMessageConverter converter() {
        return new Jackson2JsonMessageConverter();
    }

    @RabbitListener(queues = "foo")
    public void listen(Foo foo) {
        System.out.println(foo);
    }


    public static class Foo {

        public String bar;

        public String getBar() {
            return this.bar;
        }

        public void setBar(String bar) {
            this.bar = bar;
        }

        @Override
        public String toString() {
            return "Foo [bar=" + this.bar + "]";
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

我发了这条消息

发布json消息

有了这个结果:

2017-01-28 21:49:45.509  INFO 11453 --- [           main] com.example.So41914665Application        : Started So41914665Application in 4.404 seconds (JVM running for 5.298)
Foo [bar=baz]
Run Code Online (Sandbox Code Playgroud)

Boot将为您定义管理员和模板.