rabbitmq consume json message and convert into Java object

15,853

Configure the RabbitTemplate with a Jackson2JsonMessageConverter.

Then use

template.convertAndSend("myqueue", myDto);

...

SignUpDto out = (SignUpDto) template.receiveAndConvert("myQueue");

Note that the outbound conversion sets up the content type (application/json) and headers with type information that tells the receiving converter what object type to create.

If you really do want to send a simple String of JSON, you need to set the content type to application/json. To help the inbound conversion, you can either set the type headers (look at the converter source for information), or you can configure the converter with a ClassMapper to determine the type.

EDIT

<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
         message-converter="json" />

<bean id="json"
 class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />

Or, since you are using Java Config; simply inject one into your template definition.

EDIT2

If you want to send a plain JSON string; you need to help the inbound converter via headers.

To set the headers...

template.convertAndSend("", "myQueue", jsonString, new MessagePostProcessor() {

    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
        message.getMessageProperties().setContentType("application/json");
        message.getMessageProperties().getHeaders()
            .put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME, "foo.SignUpDto");
        return message;
    }
});

Bear in mind, though, that this sending template must NOT have a JSON message converter (let it default to the SimpleMessageConverter). Otherwise, the JSON will be double-encoded.

Share:
15,853
Robbo_UK
Author by

Robbo_UK

Updated on July 11, 2022

Comments

  • Robbo_UK
    Robbo_UK almost 2 years

    I have put together a java test. It puts a message on a queue and returns it as a string. What Im trying to achieve is for it to it convert into the java object SignUpDto. I have stripped down the code as much as possible for the question.

    The question:

    How do I modify the test below to convert into a object?


    SignUpClass

    public class SignUpDto {
        private String customerName;
        private String isoCountryCode;
        ... etc
    }
    

    Application - Config class

    @Configuration
    public class Application  {
    
        @Bean
        public ConnectionFactory connectionFactory() {
            return new CachingConnectionFactory("localhost");
        }
    
        @Bean
        public AmqpAdmin amqpAdmin() {
            return new RabbitAdmin(connectionFactory());
        }
    
        @Bean
        public RabbitTemplate rabbitTemplate() {
    
            // updated with @GaryRussels feedback
            RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            return rabbitTemplate;
        }
    
        @Bean
        public Queue myQueue() {
            return new Queue("myqueue");
        }
    }
    

    The Test

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {Application.class})
    public class TestQueue {
    
        @Test
        public void convertMessageIntoObject(){
    
            ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
            AmqpTemplate template = context.getBean(AmqpTemplate.class);
    
            String jsonString = "{ \"customerName\": \"TestName\", \"isoCountryCode\": \"UK\" }";
    
            template.convertAndSend("myqueue", jsonString);
    
            String foo = (String) template.receiveAndConvert("myqueue");
    
            // this works ok    
            System.out.println(foo);
    
            // How do I make this convert
            //SignUpDto objFoo = (SignUpDto) template.receiveAndConvert("myqueue");
            // objFoo.toString()  
    
        }
    }