全部开发者教程

RabbitMQ 入门教程

RabbitMQ 简介
RabbitMQ 简介

消息转换器应用实操

1. 前言

Hello,大家好。在上一节中,我们以 Jackson2JsonMessageConverter 消息转换器为例,介绍了消息转换器在使用之前的配置,以及如何初始化我们的消息转换器。本小节会继续为同学们介绍在 RabbitMQ 中,都有哪些常用的消息转换器,以及我们又该如何使用这些常用的消息转换器。

话不多说,让我们直入正题吧。

本节主要内容:

  • 常用消息转换器概述;

  • 常用消息转换器基本使用。

2. 常用消息转换器概述

在 Spring-AMQP 中,为我们提供了很多不同类型的消息转换器,这些消息转换器是针对不同的数据接收类型来进行设计的,比如 Json 数据格式、字符串数据格式、文件数据格式等,在众多消息转换器中间,在实际项目开发中使用频率较高的消息转换器,也就屈指可数,下面就让我们来看一下都有哪些常用的消息转换器吧。

消息转换器名称
JSON转换器 Jackson2JsonMessageConverter
自定义转换器

可以看到,在 Spring-AMQP 中,常用的消息转换器,常用的也就只有 Jackson2JsonMessageConverter 这一个了,但是他却可以实现我们项目中的实体类型与要接收到消息类型之间的转换,那么具体是如何实现的呢,让我们先睹为快吧。

3. 常用消息转换器基本使用

3.1 配置消息转换器基本骨架

要想使用 Jackson2JsonMessageConverter 消息转换器,首先要做的,就是初始化 Jackson2JsonMessageConverter 消息转换器,在初始化完成之后,我们可以结合一个类型映射器,来实现我们要接收的消息类型与我们所需的消息类型之间的转换, 如下代码所示:

代码实现:

// 省略连接 RabbitMQ-Server 的步骤
Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter();
DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
jsonConverter.setJavaTypeMapper(javaTypeMapper);

代码解释:

第 1-2 行,是在对 Jackson2JsonMessageConverter 消息转换器进行初始化操作,在上一小节中已经介绍过了,这里不再赘述。

第 3-4 行,我们通过实例化对象的方式,初始化了一个 DefaultJackson2JavaTypeMapper 映射器,该映射器是建立消息类型与目标数据类型进行转换的一个映射器,我们可以再其中设置我们的目标数据类型。

第 5 行,我们通过 jsonConverter 的 setJavaTypeMapper 方法,将我们初始化好的 javaTypeMapper 数据类型映射器设置到我们的 Jackson2JsonMessageConverter 消息转换器中,这样我们的消息转换器就可以将 RabbitMQ 中的消息,转换成我们所需的目标数据类型的数据了。

3.2 Jackson2JsonMessageConverter 消息转换器基本使用

在我们配置好消息转换器的基本骨架之后,我们还需要进一步配置我们的 DefaultJackson2JavaTypeMapper 数据类型映射器,即对我们所需的目标数据类型进行配置。

DefaultJackson2JavaTypeMapper 数据类型映射器,在配置消息的转换类型时,需要我们在生产端精心配置,同时,支持通过 Map 的方式来对所需的目标数据类型进行配置,在配置的时候,Map 的 key 值需要遵循特定的语法规范,而 value 值则需要配置我们所需目标数据类型的全路径, 配置代码如下所示:

代码实现:

// 省略连接 RabbitMQ-Server 的过程
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("application/json");
messageProperties.getHeaders().put("_TypeId_", "com.imooc.rabbitmq.pojo.User");
Message message = new Message(json.getBytes(), messageProperties);
// 省略消息发送过程

代码解释:

第 1 行,我们通过实例化对象的方式,对 RabbitMQ 中消息的参数部分 MessageProperties 进行了初始化操作,这是设置 RabbitMQ 中消息的消息体的"必经之路"。

第 2 行,我们通过 messageProperties 的 setContentType 方法,来对我们要发送的消息的内容类型进行设置,这里设置为了 application/json 类型,即我们的消息是以 json 串的形式发送出去的。

第 3 行,我们通过 messageProperties 的 getHeaders 方法,获取到消息体的头内容,并且通过 put 方法设置了一个头内容,这个头内容的 key 是 TypeId , value 则是 com.imooc.rabbitmq.pojo.User 全路径的 User 实体对象。

第 4 行,我们通过实例化对象的方式,初始化了一个 RabbitMQ 中的消息 Message 对象,并通过 json.getBytes() 的方式,填充了我们的消息内容,并且指定了我们设置好的 messageProperties 消息体参数。

在经过上述代码段配置之后,在生产端将消息发送出去之后,我们的消费端在获取到消息并进行消费时,此时的消息类型已经不是 RabbitMQ 中的 byte 数组类型了,而是我们指定的 User 实体类型,并且也会以 User 实体类型的方式,来将我们的消息进行返回。

Jackson2JsonMessageConverter 消息转换器是 Spring-AMQP 默认自带的一款消息转换器,其主要提供的就是我们项目中的实体,与 RabbitMQ 自带的消息类型之间进行转换,并不能提供诸如字符串、文件等形式的数据类型与 RabbitMQ 自带的消息类型之间进行一个转换。

那么,当我们需要这种类型之间的转换时,我们又该怎么做呢?这就是自定义消息转换器该发挥作用的时候了。

Tips: 使用 Jackson2JsonMessageConverter 消息转换器,需要我们首先对消息的 ContentType 进行设置,这样我们的 Jackson2JsonMessageConverter 消息转换器才能监听到这一配置。

3.3 自定义消息转换器

在 Java 世界中,一切类即可被继承,即可被实现,那么我们实现自定义消息转换器的方法,就是通过实现我们的 RabbitMQ 中的 MessageConverter 接口,并重写其中的方法进行实现。

MessageConverter 接口中只有两个方法,一个是 toMessage 方法,另一个是 fromMessage 方法,这两个方法分别负责着不同的功能实现。

这里以实现一种 RabbitMQ 中自带的消息与图片类型之间的转换,来介绍如何自定义我们的消息转换器,如下代码所示:

代码实现:

public class ImgMessageConverter implements MessageConverter {
  @Override
  public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
    return null;
  }

   @Override
  public Message fromMessage(Message message) throws MessageConversionException {
    Object ext = message.getMessageProperties.getHeaders().get("extType");
    String extType = "";
    if(ext == null){
      extType = "jpg";
    } else {
      extType = String.valueOf(ext);
    }
    // 省略拼接文件名称过程
    String imgPath = "e:/demo/imgs/" + fileName + "." + extType;
    File file = new File(imgPath);
    try{
      Files.copy(new ByteArrayInputStream(body), file);
    } Catch(Exception e){
      e.printStackTrace();
    }
    // 省略后续逻辑处理
  }
}

代码解释:

第 1-2 行,我们声明了一个名为 ImgMessageConverter 的类,并且实现了 MessageConverter 接口,重写了接口中对应的两个方法。

第 7 行,在 toMessage 方法中,由于消息类型转换不会使用到这个方法,所以在这个方法中直接返回了 null ,即在这个方法中不做任何处理。

第 11-31 行,在 fromMessage 方法中,我们依次进行了:获取消息类型,并根据类型进行判断,以及使用文件输入流的形式,将我们的图片消息类型存储到了我们的本地。

Tips: 1. Jackson2JsonMessageConverter 消息转换器基本上可以满足我们在实际项目开发中,任意实体类型与消息类型进行转换的需求,不需要我们再进行额外的配置;
2. 自定义消息转换器在处理特殊消息上,还是比较常用的,比如文中提到的字符串类型、图片类型,甚至是 Word 文档类型,这里需要同学们注意,只要自定义了消息转换器,就要在 fromMessage 中处理我们需要的文件处理方式,这样才能满足我们的业务需求;
3.消息转换器不能单独使用,需要结合消息适配器来一起使用,而 Jackson2JsonMessageConverter 消息转换器又需要搭配 DefaultJackson2JavaTypeMapper 数据类型映射器一起使用,这点同学们不要搞混淆了。

4. 小结

本小节为同学们详细介绍了在 Spring-AMQP 中常用的消息转换器的使用方法,以及在 RabbitMQ 中自带的消息转换器无法满足我们的业务需求是,如何自定义消息转换器,以满足我们的业务需求。消息转换器和消息适配器具有同等的作用,即都是为了更好的对消息进行处理而诞生的工具,同学们一定要对这两个概念进行理解和掌握。