Java 如何让Kafka消费者处理LocalDate类型?

Java 如何让Kafka消费者处理LocalDate类型?,java,spring-boot,apache-kafka,jackson,Java,Spring Boot,Apache Kafka,Jackson,我将一个字段从字符串更改为LocalDate类型,现在我的卡夫卡消费者无法处理它。在阅读了下面的错误之后,看起来我需要反序列化这个值。我原以为修改下面的consumerFactory以包含LocalDateDeserializer可以解决这个问题,但事实并非如此。我是否需要创建自定义反序列化程序,或者是否可以修改我的consumerFactory中的一些配置 Caused by: org.apache.kafka.common.errors.SerializationException: Can

我将一个字段从
字符串更改为
LocalDate
类型,现在我的卡夫卡消费者无法处理它。在阅读了下面的错误之后,看起来我需要反序列化这个值。我原以为修改下面的
consumerFactory
以包含
LocalDateDeserializer
可以解决这个问题,但事实并非如此。我是否需要创建自定义反序列化程序,或者是否可以修改我的
consumerFactory
中的一些配置

Caused by: org.apache.kafka.common.errors.SerializationException: Can't deserialize data [[...125]] from topic [Service.Topic]
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
代码:

public ConsumerFactory ConsumerFactory(){
Map config=newhashmap();
config.put(ConsumerConfig.BOOTSTRAP\u SERVERS\u config,bootstrapserver);
config.put(ConsumerConfig.KEY\u反序列化程序\u CLASS\u config,StringDeserializer.CLASS);
config.put(ConsumerConfig.KEY\u反序列化程序\u CLASS\u config,LocalDateDeserializer.CLASS);
config.put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,JsonDeserializer.CLASS);

我认为这不是卡夫卡的问题,而是杰克逊的问题

默认情况下,Kafka使用Jackson进行序列化/反序列化。您可以为
ObjectMapper
注册
JavaTimeModule
,并使用它构建
JsonDeserializer
。然后构建自定义
ConsumerFactory

public ConsumerFactory<String, Request> consumerFactory() {

     ObjectMapper objectMapper = new ObjectMapper();
     objectMapper.registerModule(new JavaTimeModule());

     Map<String, Object> config = new HashMap<>();
     config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);

     StringDeserializer keyDeserializer = new StringDeserializer();
     JsonDeserializer<Request> jsonDeserializer = new JsonDeserializer<>(objectMapper);

     ConsumerFactory<String, Request> factory = new DefaultKafkaConsumerFactory<>(config, keyDeserializer,  jsonDeserializer);
     return factory;
}

这解决了问题!我在字段声明中使用了以下注释

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)

值得注意的是,这些类在我的回答中提到的
jackson-datatype-jsr310
依赖项中可用。
@Configuration
@EnableKafka
public class KafkaConfig {
    @Bean
    public ConsumerFactory<String, Request> consumerFactory(Jackson2ObjectMapperBuilder objectMapperBuilder) {

        Map<String, Object> config = new HashMap<>();
        config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);

        StringDeserializer keyDeserializer = new StringDeserializer();
        JsonDeserializer<Request> jsonDeserializer = new JsonDeserializer<>(objectMapperBuilder.build());

        ConsumerFactory<String, Request> factory = new DefaultKafkaConsumerFactory<>(config, keyDeserializer,  jsonDeserializer);
        return factory;
    }

    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.modulesToInstall(new JavaTimeModule());
        return builder;
    }
}

@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)