Spring整合RabbitMQ消息类型转换踩坑记录
错误描述
org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Failed to convert message
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:155)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1665)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1584)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1572)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1563)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1507)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:967)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:914)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1291)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1197)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.amqp.AmqpException: No method found for class java.util.LinkedHashMap
at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getHandlerForPayload(DelegatingInvocableHandler.java:207)
at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getMethodFor(DelegatingInvocableHandler.java:339)
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.getMethodFor(HandlerAdapter.java:117)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:205)
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:146)
配置信息
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new FastJsonMessageConverter(Object.class));
return factory;
}
@Bean
@Scope("prototype")
@Primary
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new FastJsonMessageConverter(Object.class));
template.setReturnsCallback(returned -> log.debug("RabbitTemplate ReturnsCallback : {}", returned));
template.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) -> log.debug("RabbitTemplate ConfirmCallback : CorrelationData = {}, ack = {}, cause = {}", correlationData, ack, cause));
template.afterPropertiesSet();
return template;
}
对SimpleRabbitListenerContainerFactory和RabbitTemplate都添加了FastJsonMessageConverter类型的转换器。
发送端代码
/**
* 默认消息发送
*
* @param exchange
* @param queueName
* @param object
*/
public void convertAndSend(String exchange, String queueName, final Object object) {
rabbitTemplate.convertAndSend(exchange, queueName, object);
}
object为具体类型,非json转换后的字符串。
消费端代码
@Component
@RabbitListener(queues = "")
public class MonitorHandleConsumer {
@RabbitHandler
public void process(MQMessage<String> mqMessage) {
}
}
原因分析
因为我们配置了FastJsonMessageConverter,然后消费端在类上添加了RabbitListener注解
- com.imooc.amqp.FastJsonMessageConverter的fromMessage()得到com.alibaba.fastjson.JSONObject类型
- org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter的invokeHandlerAndProcessResult()根据JSONObject类型来查找对应的方法,结果没找到,因为我们的方法参数为MQMessage类型。
解决方法
两种方法
- 将RabbitListener注解标注在方法上,这样就不会根据参数类型来查找方法了。
- 去除FastJsonMessageConverter类型的转换器,消息发送是转换层json字符串,消费端方法参数也为字符串

浙公网安备 33010602011771号