消息轉(zhuǎn)換器應(yīng)用實操
1. 前言
Hello,大家好。在上一節(jié)中,我們以 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器為例,介紹了消息轉(zhuǎn)換器在使用之前的配置,以及如何初始化我們的消息轉(zhuǎn)換器。本小節(jié)會繼續(xù)為同學(xué)們介紹在 RabbitMQ 中,都有哪些常用的消息轉(zhuǎn)換器,以及我們又該如何使用這些常用的消息轉(zhuǎn)換器。
話不多說,讓我們直入正題吧。
本節(jié)主要內(nèi)容:
-
常用消息轉(zhuǎn)換器概述;
-
常用消息轉(zhuǎn)換器基本使用。
2. 常用消息轉(zhuǎn)換器概述
在 Spring-AMQP 中,為我們提供了很多不同類型的消息轉(zhuǎn)換器,這些消息轉(zhuǎn)換器是針對不同的數(shù)據(jù)接收類型來進行設(shè)計的,比如 Json 數(shù)據(jù)格式、字符串?dāng)?shù)據(jù)格式、文件數(shù)據(jù)格式等,在眾多消息轉(zhuǎn)換器中間,在實際項目開發(fā)中使用頻率較高的消息轉(zhuǎn)換器,也就屈指可數(shù),下面就讓我們來看一下都有哪些常用的消息轉(zhuǎn)換器吧。
消息轉(zhuǎn)換器名稱 | 類 |
---|---|
JSON轉(zhuǎn)換器 | Jackson2JsonMessageConverter |
自定義轉(zhuǎn)換器 | 無 |
可以看到,在 Spring-AMQP 中,常用的消息轉(zhuǎn)換器,常用的也就只有 Jackson2JsonMessageConverter 這一個了,但是他卻可以實現(xiàn)我們項目中的實體類型與要接收到消息類型之間的轉(zhuǎn)換,那么具體是如何實現(xiàn)的呢,讓我們先睹為快吧。
3. 常用消息轉(zhuǎn)換器基本使用
3.1 配置消息轉(zhuǎn)換器基本骨架
要想使用 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器,首先要做的,就是初始化 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器,在初始化完成之后,我們可以結(jié)合一個類型映射器,來實現(xiàn)我們要接收的消息類型與我們所需的消息類型之間的轉(zhuǎn)換, 如下代碼所示:
代碼實現(xiàn):
// 省略連接 RabbitMQ-Server 的步驟
Jackson2JsonMessageConverter jsonConverter = new Jackson2JsonMessageConverter();
DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
jsonConverter.setJavaTypeMapper(javaTypeMapper);
代碼解釋:
第 1-2 行,是在對 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器進行初始化操作,在上一小節(jié)中已經(jīng)介紹過了,這里不再贅述。
第 3-4 行,我們通過實例化對象的方式,初始化了一個 DefaultJackson2JavaTypeMapper 映射器,該映射器是建立消息類型與目標(biāo)數(shù)據(jù)類型進行轉(zhuǎn)換的一個映射器,我們可以再其中設(shè)置我們的目標(biāo)數(shù)據(jù)類型。
第 5 行,我們通過 jsonConverter 的 setJavaTypeMapper 方法,將我們初始化好的 javaTypeMapper 數(shù)據(jù)類型映射器設(shè)置到我們的 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器中,這樣我們的消息轉(zhuǎn)換器就可以將 RabbitMQ 中的消息,轉(zhuǎn)換成我們所需的目標(biāo)數(shù)據(jù)類型的數(shù)據(jù)了。
3.2 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器基本使用
在我們配置好消息轉(zhuǎn)換器的基本骨架之后,我們還需要進一步配置我們的 DefaultJackson2JavaTypeMapper 數(shù)據(jù)類型映射器,即對我們所需的目標(biāo)數(shù)據(jù)類型進行配置。
DefaultJackson2JavaTypeMapper 數(shù)據(jù)類型映射器,在配置消息的轉(zhuǎn)換類型時,需要我們在生產(chǎn)端精心配置,同時,支持通過 Map 的方式來對所需的目標(biāo)數(shù)據(jù)類型進行配置,在配置的時候,Map 的 key 值需要遵循特定的語法規(guī)范,而 value 值則需要配置我們所需目標(biāo)數(shù)據(jù)類型的全路徑, 配置代碼如下所示:
代碼實現(xiàn):
// 省略連接 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);
// 省略消息發(fā)送過程
代碼解釋:
第 1 行,我們通過實例化對象的方式,對 RabbitMQ 中消息的參數(shù)部分 MessageProperties 進行了初始化操作,這是設(shè)置 RabbitMQ 中消息的消息體的"必經(jīng)之路"。
第 2 行,我們通過 messageProperties 的 setContentType 方法,來對我們要發(fā)送的消息的內(nèi)容類型進行設(shè)置,這里設(shè)置為了 application/json 類型,即我們的消息是以 json 串的形式發(fā)送出去的。
第 3 行,我們通過 messageProperties 的 getHeaders 方法,獲取到消息體的頭內(nèi)容,并且通過 put 方法設(shè)置了一個頭內(nèi)容,這個頭內(nèi)容的 key 是 TypeId , value 則是 com.imooc.rabbitmq.pojo.User 全路徑的 User 實體對象。
第 4 行,我們通過實例化對象的方式,初始化了一個 RabbitMQ 中的消息 Message 對象,并通過 json.getBytes() 的方式,填充了我們的消息內(nèi)容,并且指定了我們設(shè)置好的 messageProperties 消息體參數(shù)。
在經(jīng)過上述代碼段配置之后,在生產(chǎn)端將消息發(fā)送出去之后,我們的消費端在獲取到消息并進行消費時,此時的消息類型已經(jīng)不是 RabbitMQ 中的 byte 數(shù)組類型了,而是我們指定的 User 實體類型,并且也會以 User 實體類型的方式,來將我們的消息進行返回。
Jackson2JsonMessageConverter 消息轉(zhuǎn)換器是 Spring-AMQP 默認自帶的一款消息轉(zhuǎn)換器,其主要提供的就是我們項目中的實體,與 RabbitMQ 自帶的消息類型之間進行轉(zhuǎn)換,并不能提供諸如字符串、文件等形式的數(shù)據(jù)類型與 RabbitMQ 自帶的消息類型之間進行一個轉(zhuǎn)換。
那么,當(dāng)我們需要這種類型之間的轉(zhuǎn)換時,我們又該怎么做呢?這就是自定義消息轉(zhuǎn)換器該發(fā)揮作用的時候了。
Tips: 使用 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器,需要我們首先對消息的 ContentType 進行設(shè)置,這樣我們的 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器才能監(jiān)聽到這一配置。
3.3 自定義消息轉(zhuǎn)換器
在 Java 世界中,一切類即可被繼承,即可被實現(xiàn),那么我們實現(xiàn)自定義消息轉(zhuǎn)換器的方法,就是通過實現(xiàn)我們的 RabbitMQ 中的 MessageConverter 接口,并重寫其中的方法進行實現(xiàn)。
MessageConverter 接口中只有兩個方法,一個是 toMessage 方法,另一個是 fromMessage 方法,這兩個方法分別負責(zé)著不同的功能實現(xiàn)。
這里以實現(xiàn)一種 RabbitMQ 中自帶的消息與圖片類型之間的轉(zhuǎn)換,來介紹如何自定義我們的消息轉(zhuǎn)換器,如下代碼所示:
代碼實現(xiàn):
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();
}
// 省略后續(xù)邏輯處理
}
}
代碼解釋:
第 1-2 行,我們聲明了一個名為 ImgMessageConverter 的類,并且實現(xiàn)了 MessageConverter 接口,重寫了接口中對應(yīng)的兩個方法。
第 7 行,在 toMessage 方法中,由于消息類型轉(zhuǎn)換不會使用到這個方法,所以在這個方法中直接返回了 null ,即在這個方法中不做任何處理。
第 11-31 行,在 fromMessage 方法中,我們依次進行了:獲取消息類型,并根據(jù)類型進行判斷,以及使用文件輸入流的形式,將我們的圖片消息類型存儲到了我們的本地。
Tips: 1. Jackson2JsonMessageConverter 消息轉(zhuǎn)換器基本上可以滿足我們在實際項目開發(fā)中,任意實體類型與消息類型進行轉(zhuǎn)換的需求,不需要我們再進行額外的配置;
2. 自定義消息轉(zhuǎn)換器在處理特殊消息上,還是比較常用的,比如文中提到的字符串類型、圖片類型,甚至是 Word 文檔類型,這里需要同學(xué)們注意,只要自定義了消息轉(zhuǎn)換器,就要在 fromMessage 中處理我們需要的文件處理方式,這樣才能滿足我們的業(yè)務(wù)需求;
3.消息轉(zhuǎn)換器不能單獨使用,需要結(jié)合消息適配器來一起使用,而 Jackson2JsonMessageConverter 消息轉(zhuǎn)換器又需要搭配 DefaultJackson2JavaTypeMapper 數(shù)據(jù)類型映射器一起使用,這點同學(xué)們不要搞混淆了。
4. 小結(jié)

本小節(jié)為同學(xué)們詳細介紹了在 Spring-AMQP 中常用的消息轉(zhuǎn)換器的使用方法,以及在 RabbitMQ 中自帶的消息轉(zhuǎn)換器無法滿足我們的業(yè)務(wù)需求是,如何自定義消息轉(zhuǎn)換器,以滿足我們的業(yè)務(wù)需求。消息轉(zhuǎn)換器和消息適配器具有同等的作用,即都是為了更好的對消息進行處理而誕生的工具,同學(xué)們一定要對這兩個概念進行理解和掌握。