You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kafka发送嵌套JSON对象异常:消费者仅接收根级字段问题

Kafka嵌套JSON字段反序列化返回null问题

问题描述

搭建基础Kafka项目时,发送包含嵌套List<Order>结构的UserCreate对象,消费者接收后仅根级createDate字段有值,嵌套的orders字段始终为null。

相关代码

UserCreate类

@Builder
@Jacksonized
@ToString
public class UserCreate implements Serializable {

    @JsonSerialize(using = LocalDateSerializer.class)
    @JsonDeserialize(using = LocalDateDeserializer.class)
    private final LocalDate createDate;

    private final List<Order> orders;

}

Order类

@Builder
@Jacksonized
@ToString
public class Order implements Serializable {
   private final String name;
}

生产者配置

@Bean
public ProducerFactory<String, UserCreate> transferProducerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
    return new DefaultKafkaProducerFactory<>(configProps);
}

@Bean
public KafkaTemplate<String, TransferRequest> transferKafkaTemplate() {
    return new KafkaTemplate<>(transferProducerFactory());
}

消费者配置

public ConsumerFactory<String, UserCreate> transferConsumerFactory() {
    Map<String, Object> props = new HashMap<>();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group-id");
    return new DefaultKafkaConsumerFactory<>(
        props,
        new StringDeserializer(),
        new JsonDeserializer<>(UserCreate.class));
}

@Bean
public ConcurrentKafkaListenerContainerFactory<String, UserCreate> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, UserCreate> factory =
        new ConcurrentKafkaListenerContainerFactory<>();
    factory.setConsumerFactory(transferConsumerFactory());
    return factory;
}

接收结果

Received message: UserCreate(createDate=2023-10-08, orders=null)

修复方案

1. 修正生产者KafkaTemplate泛型错误

生产者配置中KafkaTemplate的泛型错误地写为TransferRequest,但实际发送的是UserCreate对象,这会导致序列化逻辑混乱,嵌套字段无法正确被序列化。

修改后的代码:

@Bean
public KafkaTemplate<String, UserCreate> transferKafkaTemplate() {
    return new KafkaTemplate<>(transferProducerFactory());
}

2. 配置类型映射与信任包

JsonDeserializer默认无法自动识别嵌套类的类型信息,需要在生产者和消费者两端配置类型映射,同时开启信任包避免反序列化权限问题。

修改后的生产者配置

@Bean
public ProducerFactory<String, UserCreate> transferProducerFactory() {
    Map<String, Object> configProps = new HashMap<>();
    configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
    configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
    // 添加类型映射,替换为你的实体类全限定名
    configProps.put(JsonSerializer.TYPE_MAPPINGS, 
        "UserCreate:com.yourpackage.UserCreate,Order:com.yourpackage.Order");
    return new DefaultKafkaProducerFactory<>(configProps);
}

修改后的消费者配置

public ConsumerFactory<String, UserCreate> transferConsumerFactory() {
    Map<String, Object> props = new HashMap<>();
    props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
    props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group-id");
    // 与生产者一致的类型映射
    props.put(JsonDeserializer.TYPE_MAPPINGS, 
        "UserCreate:com.yourpackage.UserCreate,Order:com.yourpackage.Order");
    // 信任实体类所在的包
    props.put(JsonDeserializer.TRUSTED_PACKAGES, "com.yourpackage");
    return new DefaultKafkaConsumerFactory<>(
        props,
        new StringDeserializer(),
        new JsonDeserializer<>(UserCreate.class));
}

3. 确认实体类Jackson配置有效性

确保@Jacksonized与@Builder注解正确配合,Jackson能够处理不可变类的反序列化。如果仍有问题,可以尝试为Order类添加@JsonIgnoreProperties(ignoreUnknown = true),避免因未知字段导致反序列化失败。


内容的提问来源于stack exchange,提问作者kurt_vonnegut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:03:14