解决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'}
详细异常信息:
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
上一篇: LeetCode 回文数(巧解)