Spring + AMQP 序列化对象消息
Spring + AMQP serialise object message
我有一个使用 Spring AMQP 的 RabbitTemplate 发布消息并使用 MessageListenerAdapter 在 POJO 上订阅消息的应用程序,几乎按照 Getting Started - Messaging with RabbitMQ 指南。
void handleMessage(final String message) {...}
rabbitTemplate.convertAndSend(EXCHANGE_NAME, QUEUE_NAME, "message");
但是,这是以 String
的形式发送消息;确定有一种方法可以直接发送和接收对象消息吗?
我试过注册 JsonMessageConverter
但没有成功。
任何帮助将不胜感激 - 目前我手动 de/serialising 两边的字符串看起来很乱,我很惊讶这不是受支持的功能。
I have tried registering a JsonMessageConverter but to no avail.
最好看看你的尝试并在我们这边找出问题。
现在我只能说你应该JsonMessageConverter
发送和接收部分。
我刚刚用 gs-messaging-rabbitmq
:
测试过
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
MessageConverter messageConverter;
.....
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver, MessageConverter messageConverter) {
MessageListenerAdapter adapter = new MessageListenerAdapter(receiver, "receiveMessage");
adapter.setMessageConverter(messageConverter);
return adapter;
}
@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
.....
System.out.println("Sending message...");
rabbitTemplate.setMessageConverter(messageConverter);
rabbitTemplate.convertAndSend(queueName, new Foo("Hello from RabbitMQ!"));
其中 Receiver
已更改为:
public void receiveMessage(Foo message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
所以,输出是:
Waiting five seconds...
Sending message...
Received <Foo{foo='Hello from RabbitMQ!'}>
当我们这样使用 Foo
时:
@Override
public String toString() {
return "Foo{" +
"foo='" + foo + '\'' +
'}';
}
与适当的 getter 和 setter。
感谢@Artem 的提示。我的代码几乎符合 Getting Started Guide,我已经尝试添加 Converter
。
但正如@Artem 指出的那样,诀窍是向容器、侦听器适配器和兔子模板(在示例中自动配置)注册转换器。
所以我的 @Configuration
class 现在看起来像这样,除了 Getting Started Guide 中提到的任何内容:
@Bean
SimpleMessageListenerContainer container(final ConnectionFactory connectionFactory, final MessageListenerAdapter messageListenerAdapter,
final MessageConverter messageConverter)
{
final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(QUEUE_NAME);
container.setMessageListener(messageListenerAdapter);
container.setMessageConverter(messageConverter);
return container;
}
@Bean
RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory, final MessageConverter messageConverter)
{
final RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter);
return rabbitTemplate;
}
@Bean
MessageConverter messageConverter()
{
return new Jackson2JsonMessageConverter();
}
@Bean
Receiver receiver()
{
return new Receiver();
}
@Bean
MessageListenerAdapter listenerAdapter(final Receiver receiver, final MessageConverter messageConverter)
{
return new MessageListenerAdapter(receiver, messageConverter);
}
这意味着 Receiver
可以有一个对象方法签名,例如:
void handleMessage(final CbeEvent message)
我有一个使用 Spring AMQP 的 RabbitTemplate 发布消息并使用 MessageListenerAdapter 在 POJO 上订阅消息的应用程序,几乎按照 Getting Started - Messaging with RabbitMQ 指南。
void handleMessage(final String message) {...}
rabbitTemplate.convertAndSend(EXCHANGE_NAME, QUEUE_NAME, "message");
但是,这是以 String
的形式发送消息;确定有一种方法可以直接发送和接收对象消息吗?
我试过注册 JsonMessageConverter
但没有成功。
任何帮助将不胜感激 - 目前我手动 de/serialising 两边的字符串看起来很乱,我很惊讶这不是受支持的功能。
I have tried registering a JsonMessageConverter but to no avail.
最好看看你的尝试并在我们这边找出问题。
现在我只能说你应该JsonMessageConverter
发送和接收部分。
我刚刚用 gs-messaging-rabbitmq
:
@Autowired
RabbitTemplate rabbitTemplate;
@Autowired
MessageConverter messageConverter;
.....
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver, MessageConverter messageConverter) {
MessageListenerAdapter adapter = new MessageListenerAdapter(receiver, "receiveMessage");
adapter.setMessageConverter(messageConverter);
return adapter;
}
@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
.....
System.out.println("Sending message...");
rabbitTemplate.setMessageConverter(messageConverter);
rabbitTemplate.convertAndSend(queueName, new Foo("Hello from RabbitMQ!"));
其中 Receiver
已更改为:
public void receiveMessage(Foo message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
所以,输出是:
Waiting five seconds...
Sending message...
Received <Foo{foo='Hello from RabbitMQ!'}>
当我们这样使用 Foo
时:
@Override
public String toString() {
return "Foo{" +
"foo='" + foo + '\'' +
'}';
}
与适当的 getter 和 setter。
感谢@Artem 的提示。我的代码几乎符合 Getting Started Guide,我已经尝试添加 Converter
。
但正如@Artem 指出的那样,诀窍是向容器、侦听器适配器和兔子模板(在示例中自动配置)注册转换器。
所以我的 @Configuration
class 现在看起来像这样,除了 Getting Started Guide 中提到的任何内容:
@Bean
SimpleMessageListenerContainer container(final ConnectionFactory connectionFactory, final MessageListenerAdapter messageListenerAdapter,
final MessageConverter messageConverter)
{
final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(QUEUE_NAME);
container.setMessageListener(messageListenerAdapter);
container.setMessageConverter(messageConverter);
return container;
}
@Bean
RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory, final MessageConverter messageConverter)
{
final RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter);
return rabbitTemplate;
}
@Bean
MessageConverter messageConverter()
{
return new Jackson2JsonMessageConverter();
}
@Bean
Receiver receiver()
{
return new Receiver();
}
@Bean
MessageListenerAdapter listenerAdapter(final Receiver receiver, final MessageConverter messageConverter)
{
return new MessageListenerAdapter(receiver, messageConverter);
}
这意味着 Receiver
可以有一个对象方法签名,例如:
void handleMessage(final CbeEvent message)