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

本文介绍了SpringBoot在使用RabbitMQ时遇到的消息转换问题,特别是SimpleMessageConverter在对象序列化时可能导致的ClassNotFoundException。推荐使用Jackson2JsonMessageConverter以避免此类错误,同时展示了如何配置发送端和监听器以确保消息的正确序列化和反序列化。需要注意,若RabbitTemplate和listener的消息转换器不一致,可能会导致监听器接收消息失败。
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

消息转换错误,消息被拒绝

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值