Spring kafka在一个使用者中使用多个Message类型

时间:2016-08-20 21:27:29

标签: java spring apache-kafka

我有多个生产者可以将多种类型的事件发送到一个kafka主题。

我有一个必须消费所有类型消息的消费者。对每种类型的消息都有不同的逻辑。

    @KafkaListener(topics = "test", containerFactory = "kafkaListenerContainerFactory")
public void handleEvent(Message<EventOne> event) {
    logger.info("event={}", event);
}

但在这种情况下,所有消息都不仅仅是EventOne

如果我实现两种方法(对于每种类型的消息),那么所有消息都只有一种方法。

如果我实现这样的监听器:

    @KafkaListener(topics = "test", containerFactory = "kafkaListenerContainerFactory")
public void handleEvent(Message<?> event) {
    logger.info("event={}", event);
}

然后我得到例外: org.springframework.kafka.KafkaListenerEndpointContainer#0-0-kafka-listener-1] ERROR org.springframework.kafka.listener.LoggingErrorHandler - 处理时出错:ConsumerRecord java.lang.IllegalArgumentException:无法识别的类型:[null]

请告诉我如何实现多种类型的消费者?

1 个答案:

答案 0 :(得分:3)

我找到了灵魂,这很简单。 因此,从问题中不清楚,但我使用jsonMessageConverter 像这样:

    @Bean
ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(consumerFactory());
    factory.setMessageConverter(new StringJsonMessageConverter());
    return factory;
}

默认情况下,Jackson库不会为JSON添加类信息,因此无法猜测我想要反序列化的类型。 解决方案是注释

@JsonTypeInfo(use= JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="class")

将类信息添加到json字符串。 在消费者方面,我只写了我的活动的基类

    @KafkaListener(topics = "test", containerFactory = "kafkaListenerContainerFactory")
public void handleEvent(BasicEvent event) {

    if (event instanceof EventOne) {
        logger.info("type={EventOne}, event={}", event);
    } else {
        logger.info("type={EventTwo}, event={}", event);
    }
}

希望此信息可以帮助某人。