6

I have spent the last little while trying to get it so that my handler that is registered using @RabbitListener will have the message converted with the Jackson2JsonMessageConverter. Unfortunately no matter what configuration setup I try only the SimpleMessageConverter is used.

@Component
@Slf4j
public class TestQueueListener {
    @RabbitListener(queues = "#{@allQueue}")
    public void processMessage(String data) {
        log.trace("Message received: {}", data);
    }

    @RabbitListener(queues = "#{@invokeQueue}")
    public void processSpawnInstanceMessage(TestConfig config) {
        log.trace("Invoking with config: {}", config);

        invokeSomeMethod(config);
    }
}

This is the config I have currently that I think is closest to what is documented:

@Configuration
@EnableRabbit
public class MessagingConfiguration {
    @Bean
    public MessageConverter messageConverter() {
        ContentTypeDelegatingMessageConverter messageConverter = new ContentTypeDelegatingMessageConverter();
        messageConverter.addDelgate("application/json", new Jackson2JsonMessageConverter());
        return messageConverter;
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter);
        return rabbitTemplate;
    }

    @Bean
    public TopicExchange testExchange() {
        return new TopicExchange("test");
    }

    @Bean
    public Queue allQueue() {
        return new Queue("all", false, true, true);
    }

    @Bean
    public Binding allBinding(TopicExchange testExchange, Queue allQueue) {
        return BindingBuilder.bind(allQueue).to(testExchange).with("*");
    }

    @Bean
    public Queue invokeQueue() {
        return new Queue("invoke", false, true, true);
    }

    @Bean
    public Binding invokeBinding(TopicExchange testExchange, Queue invokeQueue) {
        return BindingBuilder.bind(invokeQueue).to(testExchange).with("invoke");
    }
}

What I understand so far, which is where I am stuck, is that RabbitTemplate is used when sending a message from the application to RabbitMQ. As such I sort of understand why my custom MessageConverter is not being used for the Handler invocation. Unfortunately I don't see how to set the MessageConverter on the incoming side. How do I use the MessageConverter that I have configured with the incoming messages?

Shawn Clark
  • 3,330
  • 2
  • 18
  • 30

1 Answers1

3

See the documentation about how to configure the listener containers created for annotated endpoints:

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(rabbitConnectionFactory());
    factory.setMessageConverter(messageConverter());
    return factory; 
}
PhoneixS
  • 10,574
  • 6
  • 57
  • 73
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • 1
    I had read that documentation a number of times and even at one point remember implementing that method that you have listed but it didn't seem to work. Tried again just now and it works great. Now working through the classMapper as my client isn't going to be providing the class type in the header. – Shawn Clark Mar 30 '15 at 22:04
  • Just stumbled upon that ClassMapper dependency too - how have you approached this problem? – Spiff Mar 15 '16 at 00:52