Java 使用Spring Kafka反序列化来自同一Kafka主题的不同JSON负载

Java 使用Spring Kafka反序列化来自同一Kafka主题的不同JSON负载,java,json,spring-boot,apache-kafka,spring-kafka,Java,Json,Spring Boot,Apache Kafka,Spring Kafka,我试图反序列化来自同一卡夫卡主题的不同JSON有效负载。这里提出的其他问题引导我进行了第一次尝试,但我无法让它运行 正如Gary所提到的()有一些提示(JsonSerializer.ADD_TYPE_INFO_HEADERS),但是当我发送和接收这两条消息时,我会得到一个异常 org.springframework.kafka.listener.ListenerExecutionFailedException:无法使用传入消息调用侦听器方法 端点处理程序详细信息: 方法[public void

我试图反序列化来自同一卡夫卡主题的不同JSON有效负载。这里提出的其他问题引导我进行了第一次尝试,但我无法让它运行

正如Gary所提到的()有一些提示(JsonSerializer.ADD_TYPE_INFO_HEADERS),但是当我发送和接收这两条消息时,我会得到一个异常

org.springframework.kafka.listener.ListenerExecutionFailedException:无法使用传入消息调用侦听器方法
端点处理程序详细信息:
方法[public void com.foo.message.ConsumerImpl.ConsumerSelf(java.lang.String、java.lang.String、java.lang.String、java.util.Map、com.foo.message.KafkaMessage、org.apache.kafka.clients.consumer.ConsumerRecord)]
Bean[com.foo.message]。ConsumerImpl@6df2a206]; 嵌套异常为org.springframework.messaging.converter.MessageConversionException:无法处理消息;嵌套异常为org.springframework.messaging.converter.MessageConversionException:无法将GenericMessage[payload=com.foo.message]的[com.foo.message.KafCamessageWithAdditionalField]转换为[com.foo.message.KafCamessage]。KafkaMessageWithAdditionalField@4e3168f7,标题={kafka_offset=22,kafka_consumer=org.apache.kafka.clients.consumer。KafkaConsumer@c0e2fcf,kafka_timestampType=CREATE_TIME,kafka_receivedMessageKey=null,kafka_receivedPartitionId=0,kafka_receivedTopic=fromBar,kafka_receivedTimestamp=1548310583481}],failedMessage=GenericMessage[payload=com.foo.message。KafkaMessageWithAdditionalField@4e3168f7,headers={kafka_offset=22,kafka_consumer=org.apache.kafka.clients.consumer。KafkaConsumer@c0e2fcf,kafka_timestampType=CREATE_TIME,kafka_receivedMessageKey=null,kafka_receivedPartitionId=0,kafka_receivedTopic=fromBar,kafka_receivedTimestamp=1548310583481}]
在org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:292)~[spring-kafka-2.2.RELEASE.jar:2.2.2.RELEASE]
在org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:79)~[spring-kafka-2.2.2.RELEASE.jar:2.2.2.RELEASE]
在org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:50)~[spring-kafka-2.2.2.RELEASE.jar:2.2.2.RELEASE]
在org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeOnMessage(KafkaMessageListenerContainer.java:1207)[spring-kafka-2.2.2.RELEASE.jar:2.2.2.RELEASE]

LoggingErrorHandler在ConsumerRecord中已经提到了一个(正确的)值

2019-01-24 07:16:27.630错误27204---[ntainer#2-0-C-1]o.s.kafka.listener.LoggingErrorHandler:处理时出错:ConsumerRecord(主题=fromBar,分区=0,偏移量=22,CreateTime=1548310583481,序列化键大小=1,序列化值大小=196,头数=RecordHeaders(头数=[],isReadOnly=false),key=null,value=com.foo.bar.message。KafkaMessageWithAdditionalField@4e3168f7)
首先是我的配置:

@EnableKafka
@配置
公共类卡夫卡消费者配置{
@值(${spring.kafka.bootstrap servers}”)
私有字符串引导服务器;
@豆子
公共ConsumerFactory consumerFactoryMessage()
{
Map props=newhashmap();
put(ConsumerConfig.BOOTSTRAP\u server\u CONFIG,bootstrapserver);
put(ConsumerConfig.KEY\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,JsonDeserializer.CLASS);
返回新的DefaultKafkanConsumerFactory(props,new StringDeserializer(),
新的JsonDeserializer(KafkaMessage.class));
}
@豆子
公共ConcurrentKafkaListenerContainerFactory kafkaListenerMessageContainerFactory()
{
ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory();
setConsumerFactory(consumerFactoryMessage());
返回工厂;
}
@豆子
公共ConsumerFactory consumerFactoryMessageWithAdditionalField()
{
Map props=newhashmap();
put(ConsumerConfig.BOOTSTRAP\u server\u CONFIG,bootstrapserver);
put(ConsumerConfig.KEY\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,JsonDeserializer.CLASS);
返回新的DefaultKafkanConsumerFactory(props,new StringDeserializer(),
新的JsonDeserializer(KafkaMessageWithAdditionalField.class));
}
@豆子
public ConcurrentKafkaListenerContainerFactory kafkaListenerMessageWithAdditionalFieldContainerFactory()
{
ConcurrentKafkListenerContainerFactory=新ConcurrentKafkListenerContainerFactory();
setConsumerFactory(consumerFactoryMessageWithAdditionalField());
返回工厂;
}
}
以下是听众:

@KafkaListener(topicPartitions=@topicPartitions(partitions=“0”,topic=“${foo.kafka.topic springBoot}”),containerFactory=“kafkaListenerMessageContainerFactory”)
public void consumerself(@Headers-Map-Map,KafkaMessage-message,ConsumerRecord-cr)
{
日志信息(“消息已接收%s”,消息);
}
@KafkaListener(topicPartitions=@topicPartitions(partitions=“0”,topic=“${foo.kafka.topic springBoot}”),containerFactory=“kafkaListenerMessageWithAdditionalFieldContainerFactory”)
public void consumerselfadd(@Headers-Map-Map,KafkaMessageWithAdditionalField消息,ConsumerRecord-cr)
{
log.info(“MessageKafCamessageWithAdditionalField接收到%s”,消息);
}

您不能这样做;您有两个不同的侦听器容器,其中的侦听器需要不同的对象

对于接收不同类型的多个侦听器方法,需要使用

@KafkaListener(id = "multi", topics = "myTopic")
static class MultiListenerBean {

    @KafkaHandler
    public void listen(String foo) {
        ...
    }

    @KafkaHandler
    public void listen(Integer bar) {
        ...
    }

    @KafkaHandler(isDefault = true`)
    public void listenDefault(Object object) {
        ...
    }

}