我正在为我的应用程序编写集成测试,向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=...
我已经尝试了这里提出的建议,并使我的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的"魔力",我最初以为在我的上下文中简单地使用下面这样的MessageConverter就可以了,但看起来情况并非如此:
@Bean
public MessageConverter jackson2Converter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
return converter;
}
谢谢! !
使用spring-amqp中的Jackson2JsonMessageConverter
-参见文档
而且,从1.6版本开始,当使用@RabbitListener注解(在方法上)时,推断的类型信息被添加到MessageProperties;…
框架根据方法签名配置转换器要转换的类型。
如果所有消息都具有相同的类型(可以使用相同的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
感谢Gary的帮助和对文档的更多阅读,我能够修复它。顺便说一下,我使用的是Spring amqp 1.5.6,即<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;
}
我有一个类似的问题,对我来说有效的是简单地将Jackson2Message消息转换器设置为
webSocketStompClient.messageConverter = new MappingJackson2MessageConverter()
我找到了有用的信息(和例子)关于这个:https://github.com/Noozen/spring-boot-websocket-client#the-java-client