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
相关推荐
起名方面没有灵感12 分钟前
力扣23.合并K个升序链表
java·算法
m0_7482333614 分钟前
Spring中WebSocket的使用
java·websocket·spring
啊烨疯狂学java21 分钟前
0105java字节面经
java·jvm·算法
我命由我1234537 分钟前
27.Java 线程间通信(synchronized 实现线程间通信、Lock 实现线程间通信)
java·开发语言·后端·java-ee·intellij-idea·juc·后端开发
迪小莫学AI38 分钟前
# LeetCode Problem 2038: 如果相邻两个颜色均相同则删除当前颜色 (Winner of the Game)
java·linux·leetcode
星辰大海的精灵40 分钟前
SpringBoot 整合 Elastic-Job 实现任务分布式调度
java·spring boot·后端
子非鱼@Itfuture1 小时前
Spark是什么?Flink和Spark区别
java·大数据·数据仓库·python·flink·spark
NHuan^_^1 小时前
RabbitMQ基础篇之Java客户端 Work Queues
java·rabbitmq·java-rabbitmq
九州~空城1 小时前
C++中map和set的封装
java·前端·c++
工一木子1 小时前
【HeadFirst系列之HeadFirst设计模式】第1天之HeadFirst设计模式开胃菜
java·设计模式·headfirst设计模式