Rabbit MQ和Spring AMQP学习四(JSON消息体)

Rabbit MQ和Spring AMQP学习四(JSON消息体)

实际应用场景中,消息的发送和接收大多数情况都是使用Java Object完成的。那么就涉及到两个问题,Producer如何发送Java对象,Consumer如何接收Java对象

Jackson2JsonMessageConverter配置

对于Java对象,Spring AMQP不建议直接使用对象的形式进行传输。建议使用JSON进行传输
在这里插入图片描述

JSON更轻量,对于发送和接收两端来说,可以更自由的解析

Producer端配置

@Bean
    public Jackson2JsonMessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }
@Bean
    public RabbitTemplate publishConfirmRabbitTemplate() {
        RabbitTemplate result = new RabbitTemplate(publishConnectionFactory());
        result.setMessageConverter(messageConverter());
        result.setBeforePublishPostProcessors(message -> {
            // 设置默认Content-Type
            if (message.getMessageProperties().getContentType() == null) {
                message.getMessageProperties().setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
            }
            if (message.getMessageProperties().getTimestamp() == null) {
                message.getMessageProperties().setTimestamp(Calendar.getInstance().getTime());
            }
            return message;
        });
      ......省略其他配置
     }

在Producer端直接设置负责发送消息的RabbitTemplate的messageConvert为Jackson.这里RabbitTemplate还设置了setBeforePublishPostProcessors方法,这个方法也是个函数式接口方法,入参为Message对象,在发送前可以加一下自定义操作。比如这里,每条消息发送时都默认带上当前Producer端时间戳

发送消息时,利用jackson将Java对象转为字节进行传输,并设置Content-Type

public void sendDirectPoJoMessage() {
        Random random = new Random(100);
        SimpleDirectEntity simpleDirectEntity = new SimpleDirectEntity();
        simpleDirectEntity.setId(random.nextLong());
        simpleDirectEntity.setName("pojo");
        simpleDirectEntity.setSimple(true);
        Message message = MessageUtils.buildPoJoMessage(simpleDirectEntity);
        rabbitTemplate.send(directExchange.getName(), "pojo" , message);
    }
public class MessageUtils {
    
    /**
     * 消息体为字符串的消息构建.
     * @param messageStr 消息字符串
     * @param contentType contentType
     * @return org.springframework.amqp.core.Message Message对象
     */
    public static Message buildStringMessage(String messageStr, String contentType) {
        MessageProperties messageProperties = MessagePropertiesBuilder.newInstance().setContentType(contentType).build();
        return new Message(messageStr.getBytes(), messageProperties);
    }
    
    /**
     * 消息体为POJO的消息构建
     * @param messagePoJo
     * @param <T>
     * @return org.springframework.amqp.core.Message Message对象
     */
    @SneakyThrows
    public static <T> Message buildPoJoMessage(T messagePoJo) {
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] bytes = objectMapper.writeValueAsBytes(messagePoJo);
       return MessageBuilder.withBody(bytes).setContentType(MessageProperties.CONTENT_TYPE_JSON).build();
    }
}

直接使用Jackson对象转字节方法,并设置ContentType为application/json.

Consumer端配置

@Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory result = new SimpleRabbitListenerContainerFactory();
        result.setConnectionFactory(connectionFactory());
        result.setPrefetchCount(2);
        result.setMessageConverter(new Jackson2JsonMessageConverter());
        return result;
    }

这里为什么在SimpleRabbitListenerContainerFactory中配置呢?前面文章分析过,每个@RabbitListener都有一个SimpleMessageListenerContainer,这个实例就是由SimpleRabbitListenerContainerFactory.createContainerInstance方法创建的,
在这里插入图片描述

也就是在创建每个Container实例时,设置当前Container的MessageConvert为Jackson的MessageConvter

Consumer端接收JSON

Producer端发送的数据为JSON字符串,Consumer端接收的时候如何自动转为对应的Java实体呢?

Spring AMQP提供了@Payload

    @RabbitListener(queues = "${queue.direct.pojo}" )
    @RabbitHandler
    public void receiveSimplePoJoQueueMessage(@Payload SimpleDirectEntity simpleDirectEntity) {
        log.info("接收到的POJO为:{}", simpleDirectEntity);
    }

这样我们就可以不用读取Message.body的字节,转为JSON字符串,再转为Java对象了。这些工作都由@Payload注解帮我们完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值