RabbitMQ基础篇之Java客户端 消息转换器

文章目录

消息转换器简介

消息转换器(Message Converter)是Spring AMQP中的一个重要组件,用于处理消息的序列化和反序列化。具体来说,它负责将Java对象转换为字节序列发送到RabbitMQ,并在消息接收时将字节序列反序列化回Java对象。

RabbitTemplate 的 convertAndSend() 方法

在Spring AMQP中,使用convertAndSend()方法来发送消息。此方法的最后一个参数是一个 Object 类型,意味着我们可以发送任何Java对象。convertAndSend() 方法不仅发送消息,还会将消息对象转换为可以在网络上传输的字节流。

java 复制代码
public void convertAndSend(String exchange, String routingKey, Object message);

其中,message 可以是字符串、集合或任何自定义Java对象,convertAndSend() 会将这些对象转为字节流发送给RabbitMQ。

消息转换器的工作原理

Spring AMQP的消息转换器会将Java对象转化为字节流,进行网络传输。当消息从RabbitMQ接收到时,字节流会通过消息转换器被反序列化为Java对象。

默认行为:

  • 发送消息时 :消息会通过 SimpleMessageConverter 转换为字节流。
  • 接收消息时:消息会被自动反序列化回Java对象。

默认的序列化方式 :Spring AMQP默认使用JDK自带的序列化机制。消息格式为 application/x-java-serialized-object

JDK 序列化的缺点

默认的 JDK 序列化虽然可以转换任意对象,但它存在几个显著的问题:

  1. 安全漏洞:JDK序列化存在反序列化攻击的风险。
  2. 体积过大:序列化后的字节流体积较大,占用带宽和存储空间。
  3. 可读性差:序列化后的字节流不可读,无法直观查看消息内容。

改进:使用 JSON 进行序列化

为了避免JDK序列化的缺点,可以使用JSON作为消息的序列化格式,这样:

  • 数据体积较小。
  • 数据可读性好。
  • 提高了消息的安全性。

如何实现:

  • 使用Jackson库将消息序列化为JSON格式。
  • 配置 Jackson2JsonMessageConverter 替代默认的 SimpleMessageConverter

实现步骤

  1. 引入Jackson依赖 首先需要在项目中引入Jackson的依赖。
xml 复制代码
<!-- jackson-->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>
  1. 配置消息转换器 在Spring的配置类中配置 Jackson2JsonMessageConverter 作为消息转换器。
java 复制代码
@Bean
public MessageConverter messageConverter() {
    return new Jackson2JsonMessageConverter();
}
  1. 自动注入到RabbitTemplate 配置好消息转换器后,Spring Boot会自动将该转换器注入到 RabbitTemplate 中,确保发送和接收消息时使用相同的转换器。
  2. 消息监听者和消费者都需要配置。

示例:发送Map类型的消息

假设我们需要发送一个包含姓名和年龄的Map对象,通过RabbitTemplate发送消息。

发送消息代码:

java 复制代码
@Test
public void testSendObject() {;
    // 消息
    Map<String, Object> msg = new HashMap<>(2);
    msg.put("name", "jack");
    msg.put("age", 20);
    // 发送消息
    rabbitTemplate.convertAndSend("object.queue", msg);
}

发送后在RabbitMQ中的格式:

  • 发送的消息会被转换为JSON格式:
json 复制代码
{"name":"Jack","age":21}
  • 此时消息的Content-Type会变为 application/json,并且消息体积更小且可读性更高。

接收消息

接收方只需要使用相同的消息转换器来处理消息:Spring会根据消息的Content-Type自动选择正确的消息转换器进行反序列化。

消费者代码示例:

java 复制代码
@RabbitListener(queues = "object.queue")
public void listenObjectQueue(Map<String, Object> message) {
    log.info("消费者接收到 object.queue 的消息: " + message);
}

此时,消费者能够正确地反序列化收到的JSON格式的消息。

验证与测试

在进行消息发送和接收时,要确保发送端和接收端使用的是相同的消息转换器。否则,如果发送端使用了JSON格式,而接收端使用了JDK序列化格式,会导致反序列化失败。

测试步骤:

  1. 发送消息时使用 Jackson2JsonMessageConverter 转换为JSON格式。
  2. 在RabbitMQ控制台查看消息时,确认消息体为JSON格式。
  3. 消费者接收到消息后,正确反序列化为Map对象。

总结

  • 默认序列化方式:Spring AMQP默认使用JDK的序列化方式,它在一些场景下并不理想,特别是在安全性、体积和可读性方面。
  • 推荐使用JSON序列化 :通过引入 Jackson2JsonMessageConverter 替代JDK序列化,可以有效提升消息的可读性,减少消息体积,并避免安全问题。
  • 配置步骤 :只需要引入Jackson依赖并配置 Jackson2JsonMessageConverter,Spring Boot会自动注入转换器,无需手动配置每个 RabbitTemplate
相关推荐
坐吃山猪2 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫3 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao3 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区4 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT5 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy5 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss7 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续7 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0447 小时前
ReAct模式解读
java·ai