无法为传入的RabbitMq消息配置解析器

时间:2016-10-27 12:47:23

标签: java spring spring-boot spring-amqp spring-rabbitmq

我正在为我的应用程序编写集成测试,以便向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)

我收到此问题:"未找到转换为转换为.."

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=...

我已经尝试了here的建议,并让我的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实例化的所有bean并从这里开始吗?什么样的豆应该在这里,以便它的工作?使用Spring Boot&#34; magic&#34;,我最初认为在我的上下文中简单地使用类似下面的MessageConverter就可以了,但看起来并非如此:

@Bean
public MessageConverter jackson2Converter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    return converter;
}  

谢谢!

4 个答案:

答案 0 :(得分:1)

使用来自spring-amqp的Jackson2JsonMessageConverter - 请参阅the documentation

  

此外,从版本1.6开始,当使用@RabbitListener注释(在方法上)时,推断的类型信息被添加到MessageProperties; ...

框架根据方法签名配置转换器将转换为的类型。

答案 1 :(得分:1)

如果所有消息都具有相同的类型(可以使用相同的MessageConverter进行反序列化),则只需将Jackson2JsonMessageConverter添加到应用程序上下文中即可:

@Bean
MessageConverter messageConverter(ObjectMapper objectMapper) {
    Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
    jackson2JsonMessageConverter.setJsonObjectMapper(objectMapper);
    return jackson2JsonMessageConverter;
}

ObjectMapper作为参数传递,可以使用Spring Boot配置属性配置Jackson。

由于我一开始并不是很清楚如何配置Spring Boot和Spring Amqp以序列化/反序列化我创建的示例项目的JSON消息,您可能需要查看:https://github.com/maciejwalkowiak/spring-boot-spring-amqp-java8-lombok-sample

答案 2 :(得分:0)

感谢Gary的帮助以及对文档的更多阅读,我能够解决它。顺便说一句,我使用的是Spring amqp 1.5.6,即&lt; 1.6。

  • 首先是我将消息作为Json字符串发送,绕过AmqpTemplate的转换器:将我的对象直接传递给amqpTemplate.convertAndSend方法,而不将其自身转换为Json,标题设置正确,以帮助接收者识别内容是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;
}

答案 3 :(得分:0)

我有一个类似的问题,对我有用的是简单地将Jackson2Message消息转换器设置为

webSocketStompClient.messageConverter = new MappingJackson2MessageConverter()

我在https://github.com/Noozen/spring-boot-websocket-client#the-java-client

上找到了有用的信息(和示例)