zoukankan      html  css  js  c++  java
  • 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

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

    作者:海绵般汲取
    出处:https://www.cnblogs.com/gne-hwz/
    版权:本文版权归作者和博客园共有
    转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
  • 相关阅读:
    ORA-01861: 文字与格式字符串不匹配
    Tomcat启动失败Unrecognized Windows Sockets error: 0: JVM_Bind
    登陆数据库,界面一直保持正在登陆的状态,oracle使用界面无法登陆
    java.sql.SQLException: 关闭的连接
    如何提高家庭宽带的网速?
    打爆IPv4的不一定是IPv6,可能是中国互联网!
    LibreOffice 7.0.1 发布,开源办公套件
    iPhone12系列售价曝光
    TikTok正式起诉特朗普政府
    WordPress主题ripro 6.6
  • 原文地址:https://www.cnblogs.com/gne-hwz/p/15668947.html
Copyright © 2011-2022 走看看