跳到主要内容
JackSparrow414
返回

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

本文导航

展开本文导航

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

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

Jackson2JsonMessageConverter配置

对于Java对象,Spring AMQP不建议直接使用对象的形式进行传输。建议使用JSON进行传输 Spring AMQP 文档建议使用 JSON 替代 Java 序列化传输消息

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方法创建的, SimpleRabbitListenerContainerFactory 创建容器并设置 MessageConverter

也就是在创建每个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注解帮我们完成


分享本文:

继续阅读本系列

RabbitMQ 与 Spring AMQP

  1. RabbitMQ和Spring AMQP学习一
  2. RabbitMQ和Spring AMQP学习二(消息模型详解、Spring AMQP启动流程分析-超详细)
  3. Rabbit MQ 和Spring AMQP学习三(消息的可靠性)
  4. Rabbit MQ和Spring AMQP学习四(JSON消息体)正在阅读
  5. RabbitMQ和Spring AMQP学习五(延迟队列)

评论

欢迎提问、纠错和分享经验。发表评论需要登录 GitHub;中英文版本共享评论。

评论仅在正式网站开放。