无法为传入的 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