有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在为向RabbitMq发送消息的应用程序编写集成测试。作为测试配置的一部分,我声明了一些RabbitListener来获取这些消息

我知道我离得不远,因为这是可行的:

 @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)]

你知道我可以试试什么吗?我不知道如何进一步调查。。我是否应该记录SpringBoot实例化的所有bean并从这里开始?这里应该有什么样的豆子才能起作用?对于Spring Boot“magic”,我最初认为在我的上下文中使用下面这样的MessageConverter就可以了,但看起来情况并非如此:

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

谢谢


共 (4) 个答案

  1. # 1 楼答案

    多亏了加里的帮助和对文档的更多阅读,我才得以修复它。顺便说一下,我正在使用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;
    }
    
  2. # 2 楼答案

    使用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;...

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

  3. # 3 楼答案

    如果所有消息都具有相同的类型(可以用相同的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