rabbitmq 消费 json 消息并转换成 Java 对象

Posted

技术标签:

【中文标题】rabbitmq 消费 json 消息并转换成 Java 对象【英文标题】:rabbitmq consume json message and convert into Java object 【发布时间】:2015-11-26 15:34:04 【问题描述】:

我已经整理了一个 java 测试。它将消息放入队列并将其作为字符串返回。我试图实现的是将它转换为 java 对象 SignUpDto。我已经为这个问题尽可能地精简了代码。

问题:

如何修改下面的测试以转换为对象?


SignUpClass

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

应用程序 - 配置类

@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");
    

测试

@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()  

    

【问题讨论】:

【参考方案1】:

RabbitTemplate 配置为Jackson2JsonMessageConverter

然后使用

template.convertAndSend("myqueue", myDto);

...

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

请注意,出站转换会设置内容类型 (application/json) 和带有类型信息的标头,这些信息告诉接收转换器要创建什么对象类型。

如果你真的想发送一个简单的 JSON 字符串,你需要将内容类型设置为application/json。为了帮助入站转换,您可以设置类型标头(查看转换器源以获取信息),也可以使用ClassMapper 配置转换器以确定类型。

编辑

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

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

或者,因为您使用的是 Java Config;只需将一个注入到您的模板定义中。

EDIT2

如果你想发送一个纯 JSON 字符串;您需要通过标头帮助入站转换器。

设置标题...

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;
    
);

但请记住,此 sending 模板必须具有 JSON 消息转换器(让它默认为 SimpleMessageConverter)。否则,JSON 将被双重编码。

【讨论】:

如何使用 Jackson2JsonMessageConverter 配置 RabbitTemplate? 我不确定 xml 是如何映射到 java 配置中的? 在您的RabbitTemplate @Bean 定义中:template.setMessageConverter(new Jackson2JsonMessageConverter()); 它现在可以工作了,感谢您的帮助 :-) 我已经更新了上面的配置设置,使其更具可读性。最后一个问题我将如何设置类型标题。 查看第二次编辑 - 但请注意最后的警告。

以上是关于rabbitmq 消费 json 消息并转换成 Java 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在php rabbitmq中将完整对象作为消息从生产者发送到消费者

rabbitmq结构

Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

分区数量超过消费者时的 Apache Kafka 消息消费

3、rabbitmq如何保证消息不被重复消费