无法为传入的 RabbitMq 消息配置解析器
Not able to configure resolver for my incoming RabbitMq message
我正在为将消息发送到 RabbitMq 的应用程序编写集成测试。作为我的测试配置的一部分,我声明了一些 RabbitListeners 来获取这些消息。
我知道我离得不远,因为这是可行的:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(
value = "myQueue",
autoDelete = "true",
exclusive = "false",
durable = "false"),
exchange = @Exchange(
value = "myExchange",
autoDelete = "true",
durable = "true"),
key = "myRoutingKey"))
public void confirmEligibilityMessage(Object eligibilityEvent) {
log.info("received message [{}]", eligibilityEvent);
receivedMessages.add(eligibilityEvent);
}
--> 收到消息
但是,我希望将消息直接转换为预期的类型,因此我通过添加有效负载的类型来修改方法的签名:
public void confirmConsolidationEligibilityMessage(@Payload EligibilityEvent eligibilityEvent)
我遇到了这个问题:"No converter found to convert to.."
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Cannot handle message
... 13 common frames omitted
Caused by: org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class messaging.outgoing.EligibilityEvent, message=GenericMessage [payload={"requestCode":"someRequestCode","isEligible":false}, headers=...
我已经尝试了建议 并使我的 GlobalEventBusListener 像这样实现 RabbitListenerConfigurer :
public class GlobalEventBusListener implements RabbitListenerConfigurer {
private final List<Object> receivedMessages = new ArrayList<>();
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
}
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
@Bean
public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(jackson2Converter());
return factory;
}
但我仍然遇到问题,因为转换没有正确发生 - 虽然消息不同..
Caused by: java.lang.IllegalStateException: No suitable resolver for argument [0] [type=messaging.outgoing.EligibilityEvent]
HandlerMethod details:
Controller [mocks.GlobalEventBusListener]
Method [public void mocks.GlobalEventBusListener.confirmEligibilityMessage(messaging.outgoing.EligibilityEvent)]
知道我可以尝试什么吗?我不确定如何进一步调查。我是否应该记录 Spring Boot 实例化的所有 beans 并从这里获取它?什么样的豆子应该放在这里才能起作用?使用 Spring Boot "magic",我最初认为只要在我的上下文中使用如下所示的 MessageConverter 就可以解决问题,但看起来并非如此:
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
谢谢!!
使用 spring-amqp 中的 Jackson2JsonMessageConverter
- 参见 the documentation。
Also, starting with version 1.6, when using @RabbitListener annotations (on methods), the inferred type information is added to the MessageProperties;...
框架根据方法签名配置转换器将转换为的类型。
如果所有消息都具有相同的类型(可以使用相同的 MessageConverter
进行反序列化),那么将 Jackson2JsonMessageConverter
添加到您的应用程序上下文就足够了:
@Bean
MessageConverter messageConverter(ObjectMapper objectMapper) {
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setJsonObjectMapper(objectMapper);
return jackson2JsonMessageConverter;
}
将 ObjectMapper
作为参数传递可让您使用 Spring 引导配置属性配置 Jackson。
因为一开始我不是很清楚如何配置 Spring Boot 和 Spring Amqp 到 serialize/deserialize JSON 消息 我创建了示例项目你可能想看看:https://github.com/maciejwalkowiak/spring-boot-spring-amqp-java8-lombok-sample
感谢 Gary 的帮助和对文档的更多阅读,我得以修复它。顺便说一句,我正在使用 Spring amqp 1.5.6,即 < 1.6.
- 第一件事是我将消息作为 Json 字符串发送,绕过 AmqpTemplate 的转换器:通过将我的 object 直接传递给
amqpTemplate.convertAndSend
方法,而不是自己将其转换为Json、headers分别设置妥当,帮助接收方识别内容是Json。
- 其次,我只需要在我的配置中添加这个:
-
@Bean
public Jackson2JsonMessageConverter jackson2Converter() {
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
return converter;
}
@Bean
public RabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory = new SimpleRabbitListenerContainerFactory();
simpleRabbitListenerContainerFactory.setConnectionFactory(connectionFactory());
simpleRabbitListenerContainerFactory.setMessageConverter(jackson2Converter());
return simpleRabbitListenerContainerFactory;
}
我遇到了类似的问题,对我有用的是简单地将 Jackson2Message 消息转换器设置为
webSocketStompClient.messageConverter = new MappingJackson2MessageConverter()
我在以下位置找到了关于此的有用信息(和示例):https://github.com/Noozen/spring-boot-websocket-client#the-java-client
我正在为将消息发送到 RabbitMq 的应用程序编写集成测试。作为我的测试配置的一部分,我声明了一些 RabbitListeners 来获取这些消息。
我知道我离得不远,因为这是可行的:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(
value = "myQueue",
autoDelete = "true",
exclusive = "false",
durable = "false"),
exchange = @Exchange(
value = "myExchange",
autoDelete = "true",
durable = "true"),
key = "myRoutingKey"))
public void confirmEligibilityMessage(Object eligibilityEvent) {
log.info("received message [{}]", eligibilityEvent);
receivedMessages.add(eligibilityEvent);
}
--> 收到消息
但是,我希望将消息直接转换为预期的类型,因此我通过添加有效负载的类型来修改方法的签名:
public void confirmConsolidationEligibilityMessage(@Payload EligibilityEvent eligibilityEvent)
我遇到了这个问题:"No converter found to convert to.."
Caused by: org.springframework.amqp.support.converter.MessageConversionException: Cannot handle message
... 13 common frames omitted
Caused by: org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class messaging.outgoing.EligibilityEvent, message=GenericMessage [payload={"requestCode":"someRequestCode","isEligible":false}, headers=...
我已经尝试了建议
public class GlobalEventBusListener implements RabbitListenerConfigurer {
private final List<Object> receivedMessages = new ArrayList<>();
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(myHandlerMethodFactory());
}
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
@Bean
public DefaultMessageHandlerMethodFactory myHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(jackson2Converter());
return factory;
}
但我仍然遇到问题,因为转换没有正确发生 - 虽然消息不同..
Caused by: java.lang.IllegalStateException: No suitable resolver for argument [0] [type=messaging.outgoing.EligibilityEvent]
HandlerMethod details:
Controller [mocks.GlobalEventBusListener]
Method [public void mocks.GlobalEventBusListener.confirmEligibilityMessage(messaging.outgoing.EligibilityEvent)]
知道我可以尝试什么吗?我不确定如何进一步调查。我是否应该记录 Spring Boot 实例化的所有 beans 并从这里获取它?什么样的豆子应该放在这里才能起作用?使用 Spring Boot "magic",我最初认为只要在我的上下文中使用如下所示的 MessageConverter 就可以解决问题,但看起来并非如此:
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
谢谢!!
使用 spring-amqp 中的 Jackson2JsonMessageConverter
- 参见 the documentation。
Also, starting with version 1.6, when using @RabbitListener annotations (on methods), the inferred type information is added to the MessageProperties;...
框架根据方法签名配置转换器将转换为的类型。
如果所有消息都具有相同的类型(可以使用相同的 MessageConverter
进行反序列化),那么将 Jackson2JsonMessageConverter
添加到您的应用程序上下文就足够了:
@Bean
MessageConverter messageConverter(ObjectMapper objectMapper) {
Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
jackson2JsonMessageConverter.setJsonObjectMapper(objectMapper);
return jackson2JsonMessageConverter;
}
将 ObjectMapper
作为参数传递可让您使用 Spring 引导配置属性配置 Jackson。
因为一开始我不是很清楚如何配置 Spring Boot 和 Spring Amqp 到 serialize/deserialize JSON 消息 我创建了示例项目你可能想看看:https://github.com/maciejwalkowiak/spring-boot-spring-amqp-java8-lombok-sample
感谢 Gary 的帮助和对文档的更多阅读,我得以修复它。顺便说一句,我正在使用 Spring amqp 1.5.6,即 < 1.6.
- 第一件事是我将消息作为 Json 字符串发送,绕过 AmqpTemplate 的转换器:通过将我的 object 直接传递给
amqpTemplate.convertAndSend
方法,而不是自己将其转换为Json、headers分别设置妥当,帮助接收方识别内容是Json。 - 其次,我只需要在我的配置中添加这个:
-
@Bean
public Jackson2JsonMessageConverter jackson2Converter() {
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
return converter;
}
@Bean
public RabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory = new SimpleRabbitListenerContainerFactory();
simpleRabbitListenerContainerFactory.setConnectionFactory(connectionFactory());
simpleRabbitListenerContainerFactory.setMessageConverter(jackson2Converter());
return simpleRabbitListenerContainerFactory;
}
我遇到了类似的问题,对我有用的是简单地将 Jackson2Message 消息转换器设置为
webSocketStompClient.messageConverter = new MappingJackson2MessageConverter()
我在以下位置找到了关于此的有用信息(和示例):https://github.com/Noozen/spring-boot-websocket-client#the-java-client