微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java RabbitMQ:无法将消息映射到相应的类

如何解决Java RabbitMQ:无法将消息映射到相应的类

我有两个不同的java spring 项目,它们通过rabbitmq 进行通信。我正在尝试发送一个 java 对象,但收到此错误消息:

org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener threw exception
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Failed to resolve class name. Class not found [com.thesis.gamamicroservices.productservice.dto.ProductCreatedDTO]

我知道问题出在生产者和消费者中应该相同的类路径中,但是由于每个项目具有不同的名称,即使它们具有完全相同的类,我也无法使类路径相同在相同的包内。

类路径存在于标题中:

headers={__TypeId__=com.thesis.gamamicroservices.productservice.dto.ProductCreatedDTO}

唯一的区别是消费者应用被称为库存服务而不是产品服务,因此它总是导致转换错误

有什么解决办法吗?我当前的临时“解决方案”正在使用原语或 java.util 类,我稍后将其转换为目标类,但它远非理想,因为我有需要发送超过 8 种不同类型对象的情况,我用完了原语对于我的@RabbitHandler...

我还通过在生产者中定义目标类路径使其工作,但由于消息被发送到多个队列/服务,因此在这里不是一个可行的解决方案。

编辑:

这是我的配置:

事件制作人:

@Configuration
public class EventProducerConfiguration {

    @Bean(name="productCreatedDeletedExchange")
    public Exchange createdDeletedExchange() {
       return new FanoutExchange("productCreatedDeletedExchange");
    }

    @Bean
    public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
        final var rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter());
        return rabbitTemplate;
    }

    @Bean
    public MessageConverter messageConverter() {
        Jackson2JsonMessageConverter messageConverter = new Jackson2JsonMessageConverter();
        DefaultClassMapper classMapper = new DefaultClassMapper();
        classMapper.setTrustedPackages("*");
        classMapper.setIdClassMapping(Map.of("created",ProductCreatedDTO.class));
        messageConverter.setClassMapper(classMapper);
        return messageConverter;
    }

}

我如何发送消息:

rabbitTemplate.convertAndSend(deletedCreatedExchange.getName(),RoutingKeys.CREATED.getNotation(),new ProductCreatedDTO(p,brand.getId(),category.getId()));

事件消费者:

@Configuration
public class EventConsumerConfiguration {

    @Bean(name="productsExchange")
    public FanoutExchange productsPubSubExchange() {
        return new FanoutExchange("productCreatedDeletedExchange");
    }

    @Bean
    public Queue productsQueue() {
        return new Queue("productsInventoryServiceQueue");
    }
    @Bean
    public Binding bindingProducts(@Qualifier("productsExchange") FanoutExchange productsExchange) {
        return BindingBuilder
                .bind(productsQueue())
                .to(productsExchange);
    }
    @Bean
    public ProductOpsReceiver productEventsReceiver() {
        return new ProductOpsReceiver();
    }
}

Ps:我不确定是否需要像在生产者配置中所做的那样在消费者配置中使用消息转换器定义rabbitTemaplate,但是这两个应用程序既是消费者又是生产者,因此定义了这些bean尽管如此。

我如何接收消息:

@RabbitListener(queues="productsInventoryServiceQueue")
public class ProductOpsReceiver {

      @RabbitHandler
      public void productCreated(ProductCreatedDTO product) {

           logger.info(PRODUCT_CREATED_LOG,product.getId());

      }
}

解决方法

我想您正在使用 Jackson2JsonMessageConverter

您可以将类型映射添加到转换器的 typeMapper。

生产者方面

mapper.setIdClassMapping(Map.of(ProductCreatedDTO.class,"created"));

在消费者端,将目标类映射到相同的标记。

类型映射器将使用类型 ID 标头(在本例中为 created)查询映射以确定要使用的类型。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?