Search code examples
javaspringspring-bootrabbitmqspring-amqp

Content type different in RabbitListener Spring AMQP using ContentTypeDelegatingMessageConverter


Actually I'm using Spring AMQP to consume XML from Rabbit.

Here is my code for Listen the queue.

  @RabbitListener(queues = DealerReceiverConfig.P8_QUEUE_NAME, id = Constants.P8_QUEUE_ID)
@SendTo("foo.bar")
public RequestDocument p8ContentReceiveMessage(RequestDocument request) {

System.out.println(request.getCorrelationId());

return request;

}

and my rabbit template configuration is:

@Override
@Bean(name = "dealerRabbit")
public RabbitTemplate rabbitTemplateSeguros(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(producerMessageConverter());
return template;
}

@Override
@Bean
public MessageConverter producerMessageConverter() {

ContentTypeDelegatingMessageConverter messageConverter = new ContentTypeDelegatingMessageConverter();

Jackson2JsonMessageConverter jsonMessageConverter = new Jackson2JsonMessageConverter();
messageConverter.addDelegate("application/json", jsonMessageConverter);

MarshallingMessageConverter marshaller = new MarshallingMessageConverter();
marshaller.setMarshaller(oxmMarshaller());
marshaller.setUnmarshaller(oxmUnMarshaller());
messageConverter.addDelegate("application/xml", marshaller);

return messageConverter;
}

@Bean
public Marshaller oxmMarshaller() {

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("foo.bar.model");
return marshaller;

}


@Bean
public Unmarshaller oxmUnMarshaller() {

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("foo.bar.model");
return marshaller;

}

The problem is when I see the returned message in the @SentTo queue configured, I get the following message.

Returned message

Any suggestions?

Thanks for your help.


Solution

  • The template is not used to send replies from @RabbitListeners; you need to add the converter to the RabbitListenerContainerFactory (Simple... or Direct..., depending on which container type you are using).

    EDIT

    It's a bug; you should be able to do this...

        @RabbitListener(queues = "foo")
        @SendTo("bar")
        public Message<String> listen(String in) {
            System.out.println(in);
            return MessageBuilder.withPayload(in.toUpperCase())
                    .setHeader(MessageHeaders.CONTENT_TYPE, "application/xml")
                    .build();
        }
    

    But the adapter still uses a raw MessageProperties which has application/x-java-serialized-object as the default CT.

    https://github.com/spring-projects/spring-amqp/issues/1219