Spring 使用兔子侦听器的 amqp 转换器问题
Spring amqp converter issue using rabbit listener
我想我在这里遗漏了一些东西..我正在尝试创建简单的兔子监听器,它可以接受自定义对象作为消息类型。现在根据文档它说
在 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}]
我的配置:
@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();
}
还有一个问题是这个异常消息没有放回队列中。
我正在使用 spring 引导 1.4,它带来了 amqp 1.6.1。
Edit1 :我按上面的方式添加了 jackson 转换器(spring 引导可能不需要),并在 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}]
如果您使用的是引导程序,您只需在配置中添加一个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 + "]";
}
}
}
我发了这条消息
结果如下:
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]
Boot 将为您定义一个管理员和模板。
我想我在这里遗漏了一些东西..我正在尝试创建简单的兔子监听器,它可以接受自定义对象作为消息类型。现在根据文档它说
在 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}]
我的配置:
@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();
}
还有一个问题是这个异常消息没有放回队列中。
我正在使用 spring 引导 1.4,它带来了 amqp 1.6.1。
Edit1 :我按上面的方式添加了 jackson 转换器(spring 引导可能不需要),并在 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}]
如果您使用的是引导程序,您只需在配置中添加一个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 + "]";
}
}
}
我发了这条消息
结果如下:
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]
Boot 将为您定义一个管理员和模板。