以下是我的代码段。
MQConfiguration
用于配置的课程
@Configuration
public class MQConfiguration {
@Bean
public Receiver receiver() {
return new Receiver();
}
}
Receiver
类
@RabbitListener(queues = "testMQ")
public class Receiver {
@RabbitHandler
public void receive(Message msg){
System.out.println(msg.toString());
}
}
以下是我发送给 RabbitMQ
的JSON消息{
"id": 1,
"name": "My Name",
"description": "This is description about me"
}
但是,当我运行我的应用程序时,我收到了以下错误消息。
2017-02-28 17:16:35.931 WARN 11828 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.
org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:872) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:782) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:702) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:95) [spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:186) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1227) [spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:683) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1181) [spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1165) [spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1500(SimpleMessageListenerContainer.java:95) [spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1367) [spring-rabbit-1.7.0.RELEASE.jar:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
Caused by: org.springframework.amqp.AmqpException: No method found for class [B
at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getHandlerForPayload(DelegatingInvocableHandler.java:127) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getMethodNameFor(DelegatingInvocableHandler.java:224) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.getMethodAsString(HandlerAdapter.java:61) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:140) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:106) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:779) ~[spring-rabbit-1.7.0.RELEASE.jar:na]
... 10 common frames omitted
那么,如果我想要的是在receive()
方法中打印JSON消息,我该怎么办?我真的很感激任何人都能对此有所了解。 :)
答案 0 :(得分:1)
如果您使用Spring Boot,则只需配置:
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
否则你必须配置:
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
...
factory.setMessageConverter(new Jackson2JsonMessageConverter());
...
return factory;
}
答案 1 :(得分:1)
我知道距离上次回复已经有一段时间了,但我想添加我的答案。以防万一其他人遇到同样的问题。
当我设置像你这样的接收器时,我遇到了类似的问题,我无法将 RabbitMQ 消息正文中的 JSON 转换为我的对象。它只是返回一条这样的错误消息。
org.springframework.amqp.rabbit.support.ListenerExecutionFailedException: Failed to convert message
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:146) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1654) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1573) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1561) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1552) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1496) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:968) [spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:914) [spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83) [spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1289) [spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1195) [spring-rabbit-2.3.9.jar:2.3.9]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_271]
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:185) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getMethodFor(DelegatingInvocableHandler.java:317) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.getMethodFor(HandlerAdapter.java:110) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:192) ~[spring-rabbit-2.3.9.jar:2.3.9]
at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:137) ~[spring-rabbit-2.3.9.jar:2.3.9]
... 11 common frames omitted
在不同的网站上搜索了几个小时没有任何好的答案后,我终于发现@RabbitListener 在课堂级别不起作用。但是,当您将其移至方法级别时,它可以正常工作。
所以,我删除了@RabbitHandler 并将@RabbitListener 移到了接收方法中。
您的接收器代码在编辑后应如下所示。
public class Receiver {
@RabbitListener(queues = "testMQ")
public void receive(Message msg){
System.out.println(msg.toString());
}
}
我仍然不完全理解为什么它在类级别不起作用。如果有人有好的解释,请在评论部分分享。非常感谢。
来源:https://titanwolf.org/Network/Articles/Article?AID=0f214d79-10f0-4b4c-9478-607428770256#gsc.tab=0
答案 2 :(得分:0)
为了将JSON发送到RabbitMQ并通过Spring Boot使用它,我们需要设置content_type
。
让我用一个示例来描述我有一个Python Producer和Java使用者(我将JSON从Python发送到RabbitMQ,Spring Boot Java应该接收JSON任务)。
有两种解决方案:
解决方案1:发送为JSON字符串并使用Jakson或GSON手动转换
您需要设置content_type =“text / plain”并将JSON转换为字符串。然后在Spring端,使用带有字符串的函数作为侦听器的输入并手动转换对象。
RabbitHandler:
@RabbitHandler
public void receive(String inputString) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
SimStatusReport theResult = objectMapper.readValue(inputString, SimStatusReport.class);
System.out.println("String instance " + theResult.toString() +
" [x] Received");
}
SimStatusReport对象:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SimStatusReport {
private String id;
private int t;
}
这是我的Python代码:
import pika
import json
import uuid
connectionResult = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channelResult = connectionResult.channel()
routing_key_result = 'sim_results'
channelResult.queue_declare(queue=routing_key_result, durable=True)
def publish_result(sim_status):
message =json.dumps(sim_status)
channelResult.basic_publish(exchange='',
routing_key=routing_key_result,
body=message,
properties=pika.BasicProperties(
content_type="text/plain",
content_encoding= 'UTF-8',
delivery_mode=2, # make message persistent
))
print("Sent ", message)
newsim_status = {'id': str(uuid.uuid4()), 't': 0}
publish_result(newsim_status)
解决方案2:发送JSON字符串并让Jackson2JsonMessageConverter自动为您进行转换。
您需要设置content_type =“application / json”。然后,您需要在RabbitMQ请求的标头中将适当的标头添加到__TypeId__
。您需要包含对象的确切名称空间,以便杰克逊不会转换。
以下是使用Python的示例(只是publish_result功能):
def publish_result(sim_status):
message =json.dumps(sim_status)
channelResult.basic_publish(exchange='',
routing_key=routing_key_result,
body=message,
properties=pika.BasicProperties(
content_type="application/json"
headers={'__TypeId__': 'com.zarinbal.simtest.run.model.SimStatusReport'},
content_encoding= 'UTF-8',
delivery_mode=2, # make message persistent
))
print("Sent ", message)
然后您需要配置Java以使用Jackson2JsonMessageConverter:
@Configuration
public class RabbitConfiguration {
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
}
这是你的倾听者:
@RabbitListener(queues = "sim_results")
public class TaskReceiver {
@RabbitHandler
public void receive(SimStatusReport in) {
System.out.println("Object instance " + in +
" [x] Received");
}
}
注意:强> 确保所有对象都具有所有属性和所有参数构造函数的setter和getter。我使用来自lombok的@ Data,@ NoArgsConstructor和@AllArgsConstructor自动生成它
答案 3 :(得分:0)
以简单的方式可以使用此功能new String(Messages)
@RabbitListener(queues = "testMQ")
public class Receiver {
@RabbitHandler
public void receive(Message msg){
String MQMessage = new String(msg.getBody());
System.out.println(MQMessage);
}
}