RabbitMQ 未序列化消息,错误转换

RabbitMQ not serialize message, error convert

我在这里看到了一些相关的问题,但是 none 对我有用,兔子不会序列化我来自另一个应用程序的消息。

Caused by: org.springframework.amqp.AmqpException: No method found for class [B

低于我的配置class接收消息。

@Configuration
public class RabbitConfiguration implements RabbitListenerConfigurer{

    public final static String EXCHANGE_NAME = "wallet-accounts"; 
    public final static String QUEUE_PAYMENT = "wallet-accounts.payment";
    public final static String QUEUE_RECHARGE = "wallet-accounts.recharge";

    @Bean
    public List<Declarable> ds() {
        return queues(QUEUE_PAYMENT, QUEUE_RECHARGE);
    }

    @Autowired
    private ConnectionFactory rabbitConnectionFactory;

    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(rabbitConnectionFactory);
    }

    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(EXCHANGE_NAME);
    }

    private List<Declarable> queues(String ... names){
        List<Declarable> result = new ArrayList<>();

        for (int i = 0; i < names.length; i++) {
            result.add(makeQueue(names[i]));
            result.add(makeBinding(names[i]));
        }
        return result;
    }

    private static Binding makeBinding(String queueName){
        return new Binding(queueName, DestinationType.QUEUE, EXCHANGE_NAME, queueName, null);
    }

    private static Queue makeQueue(String name){
        return new Queue(name);
    }

    @Bean
    public MappingJackson2MessageConverter jackson2Converter() {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        return converter;
    }

    @Bean
    public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
        DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
        factory.setMessageConverter(jackson2Converter());
        return factory;
    }

    @Override
    public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
        registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
    }
}

使用这个其他配置,报错也差不多:

Caused by: org.springframework.amqp.support.converter.MessageConversionException: failed to resolve class name. Class not found [br.com.beblue.wallet.payment.application.accounts.PaymentEntryCommand]

配置:

@Configuration
public class RabbitConfiguration {

    public final static String EXCHANGE_NAME = "wallet-accounts"; 

    public final static String QUEUE_PAYMENT = "wallet-accounts.payment";
    public final static String QUEUE_RECHARGE = "wallet-accounts.recharge";

    @Bean
    public List<Declarable> ds() {
        return queues(QUEUE_PAYMENT, QUEUE_RECHARGE);
    }

    @Autowired
    private ConnectionFactory rabbitConnectionFactory;

    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(rabbitConnectionFactory);
    }

    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(EXCHANGE_NAME);
    }

    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    private List<Declarable> queues(String ... names){
        List<Declarable> result = new ArrayList<>();

        for (int i = 0; i < names.length; i++) {
            result.add(makeQueue(names[i]));
            result.add(makeBinding(names[i]));
        }
        return result;
    }

    private static Binding makeBinding(String queueName){
        return new Binding(queueName, DestinationType.QUEUE, EXCHANGE_NAME, queueName, null);
    }

    private static Queue makeQueue(String name){
        return new Queue(name);
    }
}

谁能告诉我这些设置有什么问题,或者缺少什么?

No method found for class [B

意味着有一个默认值 SimpleMessageConverter 无法转换您传入的 application/json。它只是不知道 content-type,只是退回到 byte[] 到 return。

Class not found [br.com.beblue.wallet.payment.application.accounts.PaymentEntryCommand]

表示Jackson2JsonMessageConverter不能转换你的application/json因为传入的__TypeId__头,代表class的内容,在本地class路径。

好吧,您的 DefaultMessageHandlerMethodFactory 配置肯定对 AMQP 转换没有意义。您应该考虑使用 SimpleRabbitListenerContainerFactory bean 定义及其 setMessageConverter。是的,考虑注入正确的 org.springframework.amqp.support.converter.MessageConverter 实现。

https://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#async-annotation-conversion

从 Spring 启动的角度来看,有 SimpleRabbitListenerContainerFactoryConfigurer 可以配置这件事:

https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/htmlsingle/#boot-features-using-amqp-receiving