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

Spring Kafka消费者反序列化报cannot deserialize错误

报错原因

cannot deserialize from Object value (no delegate- or property-based Creator)是Jackson反序列化时找不到合法对象创建入口抛出的异常,具体触发逻辑:

  • 你编写的Payload实体类只定义了全参构造方法,Java语法规则下,只要类中显式定义了任意构造函数,JVM就不会自动生成无参构造
  • Spring Kafka集成的JsonDeserializer默认走无参实例化+setter赋值的反序列化流程,没有无参构造时无法创建Payload实例,直接抛出异常。
修复方案

任选以下一种方式修改即可解决问题:

  • 方案1:为Payload类添加无参构造函数,改动最小,原有逻辑不需要调整。修改后的Payload类代码如下:
public class Payload {
    private List<JsonNode> fields;
    private String name;
    private String type;

    // 新增无参构造,供Jackson反序列化时实例化对象
    public Payload() {
    }

    public Payload(List<JsonNode> fields, String name, String type) {
        this.fields = fields;
        this.name = name;
        this.type = type;
    }

    public List<JsonNode> getFields() {
        return fields;
    }

    public void setFields(List<JsonNode> fields) {
        this.fields = fields;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}
  • 方案2:如果不想保留无参构造,可以通过Jackson注解指定全参构造为反序列化入口,在构造方法和参数上添加对应注解即可:
public class Payload {
    private List<JsonNode> fields;
    private String name;
    private String type;

    @JsonCreator
    public Payload(
            @JsonProperty("fields") List<JsonNode> fields,
            @JsonProperty("name") String name,
            @JsonProperty("type") String type) {
        this.fields = fields;
        this.name = name;
        this.type = type;
    }

    // 原有getter、setter方法保持不变
    public List<JsonNode> getFields() {
        return fields;
    }

    public void setFields(List<JsonNode> fields) {
        this.fields = fields;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }
}

注意:使用该方案需要确保项目中已经引入Jackson的annotation依赖,Spring Boot生态下默认会随spring-kafka自动引入,不需要额外添加。

  • 方案3:如果不需要对消息字段做强类型绑定,直接使用Jackson原生的JsonNode作为消费值类型即可,省去自定义实体类的步骤,对应修改消费者配置:
@EnableKafka
@Configuration
public class KafkaStreamReaderConfig {
    @Bean
    public ConsumerFactory<String, JsonNode> consumerFactory(){
        Map<String,Object> config = new HashMap<>();
        config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"localhost:9092");
        config.put(ConsumerConfig.GROUP_ID_CONFIG, "groupId");
        config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
        return new DefaultKafkaConsumerFactory<>(config, new StringDeserializer(), new JsonDeserializer<>(JsonNode.class));
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, JsonNode> kafkaListener(){
        ConcurrentKafkaListenerContainerFactory<String, JsonNode> factory = new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }
}

补充:原配置中ConcurrentKafkaListenerContainerFactory没有指定泛型,属于原生类型使用,会产生编译警告,补上对应泛型参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 22:48:22