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

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