Reputation: 815
I have an application that publishes a message using Spring AMQP’s RabbitTemplate and subscribes to the message on a POJO using MessageListenerAdapter, pretty much as per the Getting Started - Messaging with RabbitMQ guide.
void handleMessage(final String message) {...}
rabbitTemplate.convertAndSend(EXCHANGE_NAME, QUEUE_NAME, "message");
However, this is sending messages as String
's; surely there is a way to send and receive Object messages directly?
I have tried registering a JsonMessageConverter
but to no avail.
Any help would be greatly appreciated - at present I'm manually de/serialising Strings on either side which seems messy and I'm surprised this isn't a supported feature.
Upvotes: 1
Views: 3710
Reputation: 815
Thanks @Artem for the hints. My code is pretty much as per the Getting Started Guide and I had already tried adding a Converter
.
But as @Artem has pointed out, the trick is to register the converter with both the container, the listener adapter, and the rabbit template (which was auto-configured in the example).
So my @Configuration
class now looks like so, in addition to whatever is mentioned in the 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);
}
which means the Receiver
can have an Object method signature such as:
void handleMessage(final CbeEvent message)
Upvotes: 1
Reputation: 121272
I have tried registering a JsonMessageConverter but to no avail.
It would be better to see your attempt and figure out the issue on our side.
Right now I only can say that you should supply JsonMessageConverter
for both sending and receiving parts.
I've just tested with the 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!"));
Where Receiver
has been changed to this:
public void receiveMessage(Foo message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
So, the output is:
Waiting five seconds...
Sending message...
Received <Foo{foo='Hello from RabbitMQ!'}>
when we use Foo
like this:
@Override
public String toString() {
return "Foo{" +
"foo='" + foo + '\'' +
'}';
}
with appropriate getter and setter.
Upvotes: 1