springboot配置rabbitmq的序列化反序列化格式


SpringBoot封裝了rabbitmq中,發送對象和接收對象時,會統一將對象和消息互相轉換
會用到MessageConverter轉換接口

 

在發送消息時,

會將Object轉換成Message Message createMessage(Object object, MessageProperties messageProperties)

 

接收消息時

SimpleMessageListenerContainer容器監聽消息時,會調用SimpleMessageListenerContainer.messageListener的消息轉換器將Message轉換成對象 Object fromMessage(Message message)

 

Springboot中,默認的rabbitMq的序列化類是:SimpleMessageConverter

 

SimpleMessageConverter
將Object對象 和 Message 互相轉換的規則

如果是 byte[] 或者 String 類型,直接獲取字節 String.getBytes(this.defaultCharset)
設置messageProperties的 contentType = text/plain

如果是其他對象,調用 SerializationUtils.serialize(object) 進行序列化
設置messageProperties的 contentType = application/x-java-serialized-object
這里存在一個問題
如果發送方: object類是 com.zwh.user
但是接受方沒有這個路徑的類時,會拋出異常,not found class
 
所以發送消息時,最好手動將消息轉換成String

Jackson2JsonMessageConverter 轉換器

序列化時,Object 轉成 json字符串在設置到 Message.body()中。 調用的是 jackson的序列化方式
反序列化時,將 Message.body()內容反序列化成 Object
這個方式不會出現上面SimpleMessageConverter轉換器的 not found class錯誤

如果項目中要統一的序列化格式, 需要顯示聲明 轉換bean

@Bean
public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
    return new Jackson2JsonMessageConverter();
}
因為自動配置類RabbitAutoConfiguration 和 RabbitAnnotationDrivenConfiguration
會自動獲取Spring 容器中MessageConverter實現類bean數據
並將轉換器設置到 RabbitTemplate 和 SimpleRabbitListenerContainerFactory.setMessageConverter() 中

RabbitAutoConfiguration 配置 發送端 RabbitTemplate 
RabbitAnnotationDrivenConfiguration 配置接收端 SimpleRabbitListenerContainerFactory

 

 

注意:如果 RabbitTemplate 配置的 jackson 序列化,而 listener沒有配置(默認SimpleMessageConverter),則接受消息轉換成object時將會報錯
如下配置
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,
                                                 MessageProcess messageProcess) {
    ReliableRabbitTemplate template = new ReliableRabbitTemplate(messageProcess);
    template.setConnectionFactory(connectionFactory);

    template.setMessageConverter(new Jackson2JsonMessageConverter());
}

 

發送端:

ProjectInfoDto projectInfoDto = new ProjectInfoDto();
projectInfoDto.setId(String.valueOf(System.currentTimeMillis()));
projectInfoDto.setProjectName("測試項目");
rabbitTemplate.sendMsgAndSaveRecord(ProjectMqConstants.PROJECT_DELETE_QUEUE, projectInfoDto.getId(),
        ProjectMqConstants.CONTRACT_OR_PROJECT_EXCHANGE, ProjectMqConstants.PROJECT_DELETE_QUEUE,
        projectInfoDto);

 

監聽器:下面的會拋出異常

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(value = ProjectMqConstants.PROJECT_DELETE_QUEUE, durable = "true", autoDelete = "false"),
    exchange = @Exchange(value = ProjectMqConstants.CONTRACT_OR_PROJECT_EXCHANGE, type = ExchangeTypes.DIRECT),
    key = ProjectMqConstants.PROJECT_DELETE_QUEUE))
public void projectCanDelete(@Payload ProjectInfoDto data,
                             Message message,
                              Channel channel) {
                                  
 }

 

報錯為:

ListenerExecutionFailedException: Listener method could not be invoked with the incoming message
Fatal message conversion error; message rejected; it will be dropped or routed to a dead letter exchange

消息轉換錯誤,消息被拒絕

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM