欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

解决rabbitmq无限循环异常问题亲测 Caused by: org.springframework.amqp.AmqpException: No method found for class [B

程序员文章站 2022-07-15 11:21:21
...

springboot项目: 2.2.2版本

rabbitmq 踩坑: 后台无限循环抛出以下异常

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

解决办法:
主要是mq的config类配置问题,第二个是实体序列化问题

config配置

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


//@Component    //网上有人说去掉这个注解,经试验,无效
@Configuration  //这个注解跟上面那个差不多,但是会比上面那个优先加载
//@EnableRabbit //看见有些会添加这个注解,注释掉也没有什么影响
public class RabbitMQConfig {

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory factory){
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(factory);
        //解决: Caused by: org.springframework.amqp.AmqpException: No method found for class [B 异常
        //消息转换器,消息转化为json, setMessageConverter(MessageConverter ),这个方法就是这次异常的解决方案,创建一个Jackson2JsonMessageConverter对象放进去
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        return rabbitTemplate;
    }

    @Bean
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(ConnectionFactory factory){
        SimpleRabbitListenerContainerFactory srlcf = new SimpleRabbitListenerContainerFactory();
        srlcf.setConnectionFactory(factory);
        //当消息有异常内容时(例如类型不匹配),将不再重新放入队列,直接丢弃
        srlcf.setDefaultRequeueRejected(false);

        //设置消息转为json
        Jackson2JsonMessageConverter j2jmc = new Jackson2JsonMessageConverter();
        srlcf.setMessageConverter(j2jmc);
        return srlcf;
    }

    //发送消息时如不配置序列化方法则按照java默认序列化机制,则会造成发送编码不符合
    @Bean
    public MessageConverter messageConverter(){
        Jackson2JsonMessageConverter j2jmc = new Jackson2JsonMessageConverter();
        return j2jmc;
    }

}

还有其它版本说:

1. 监听mq的时候以 byte 数组接收,然后再转化为 json, 这个方案确实可以, 但是每次都是这样弄不太友好,而且转化为json之后还要根据消息的类型强转为实体,容易出错

2.实体类实现序列化接口即可(这个确实是造成这个异常是原因之一,但不是最终解决方案,一般都是要实现序列化接口的,这个解决了问题的前提是config配置类已经配置好了的)

[email protected]说是方法级别注解,不能放在类上(纯属扯淡,最基本的注解使用都不懂,就好像@RequestMapping注解一样的道理)

还有其它方案不再一一解述

附:
实体类:

public class Order implements Serializable {
	//发送的实体需要序列化
    private static final long serialVersionUID = 1L;
    private String id;
    private String name;
    private String status;

	//get,set方法不多说,都懂
}

底层发送基础类:

@Component
public class MsgSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //@Autowired
    //private AmqpTemplate amqpTemplate;

    public boolean send(String exchange,String routingKey,Object object){
        try {
            rabbitTemplate.convertAndSend(exchange,routingKey,object);
        } catch (AmqpException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}

发送类:

    //Direct交换器模式,发布订阅
    @GetMapping("/send/{msg}")
    public Object send(@PathVariable("msg") String msg){
        Order order = new Order();
        order.setId(UUID.randomUUID().toString());
        order.setName("华为手机");
        order.setStatus("1");
        boolean send = msgSender.send(exchange, routingKey, order);
        if(send){
            return msg+order;
        }
        return "500,发送失败";
    }

监听类

@Component
@RabbitListener(bindings = {
        @QueueBinding(
                value = @Queue(value = "myque",durable = "true"),
                exchange = @Exchange(value = "myexchange",type = ExchangeTypes.DIRECT,ignoreDeclarationExceptions = "true",durable = "true"),
                key = "mykey"
        )
})
public class DirectListen {
    @RabbitHandler
    public void testConsumer(Order order){
        /*String result = null;
        try {
            result = new String(res, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }*/
        System.out.println("I am consumer,that is msg:"+order);
    }


}

监听结果:

I am consumer,that is msg:Order{id='ae1bbc15-49ef-4c3b-9c96-cbcc4b944f98', name='华为手机', status='1'}

解决rabbitmq无限循环异常问题亲测 Caused by: org.springframework.amqp.AmqpException: No method found for class [B

详细异常信息:

2020-06-14 12:11:02.918  WARN 9408 --- [ntContainer#0-1] o.s.a.s.c.Jackson2JsonMessageConverter   : Could not convert incoming message with content-type [application/x-java-serialized-object], 'json' keyword missing.
2020-06-14 12:11:02.918  WARN 9408 --- [ntContainer#0-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.

org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Listener method 'no match' threw exception
	at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:219) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:143) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:132) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1569) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1488) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1476) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1467) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1411) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:958) [spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:908) [spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81) [spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1279) [spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1185) [spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]
Caused by: org.springframework.amqp.AmqpException: No method found for class [B
	at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getHandlerForPayload(DelegatingInvocableHandler.java:149) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.invoke(DelegatingInvocableHandler.java:129) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:61) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:211) ~[spring-rabbit-2.2.2.RELEASE.jar:2.2.2.RELEASE]
	... 13 common frames omitted