You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Kafka Consumer无法通过JsonDeserializer消费905字节消息

排查Spring Kafka消费者反序列化失败问题

我来帮你梳理下Spring Kafka消费者反序列化失败的常见原因和解决办法,结合你给出的场景,咱们一步步排查:

可能的原因及解决方案

  • 序列化/反序列化配置不匹配
    这是最容易踩的坑!生产者使用的序列化器必须和消费者的反序列化器完全对应。比如你用Jackson2JsonSerializer序列化JSON消息,消费者就必须用Jackson2JsonDeserializer,绝对不能混用StringSerializer这类不匹配的序列化器。
    检查你的配置文件:

    • 生产者配置:spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
    • 消费者配置:spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
      另外,消费者必须明确指定反序列化的目标实体类:要么通过配置项spring.kafka.consumer.properties.spring.json.value.default.type=com.yourpackage.YourPayloadClass全局指定,要么在@KafkaListener的方法参数里直接写@Payload YourPayloadClass payload来精准指定。
  • Lombok注解与Jackson映射不匹配
    从你给出的实体类片段来看,你用了@JsonProperty和Lombok注解,这里有两个高频出错点:

    1. 无参构造函数缺失:Jackson反序列化必须依赖无参构造函数,你写的NoArgsConst...应该是没写完,一定要补全@NoArgsConstructor;如果实体类里有final字段,还要加上@NoArgsConstructor(force = true)来强制生成无参构造。
    2. JsonProperty大小写不匹配:JSON里的键是FILE_LISTKey3这种大小写混合的格式,你的@JsonProperty必须严格对应这些名称,比如JSON里是Key3,实体类里就必须写@JsonProperty("Key3"),大小写错一个都会导致Jackson找不到字段,直接触发反序列化失败。
  • 消息内容完整性问题
    虽然你的消息只有905字节,远小于Kafka默认的消息大小限制,但还是要确认消息在传输过程中有没有损坏或截断。你可以用Kafka自带的控制台消费者工具查看原始消息内容:

    kafka-console-consumer.sh --bootstrap-server your-broker-address:9092 --topic your-topic-name --from-beginning --property value.deserializer=org.apache.kafka.common.serialization.StringDeserializer
    

    看看输出的JSON是不是和你生产的完全一致,有没有乱码、缺失字段或者语法错误。如果内容不对,还要检查压缩配置:生产者开启了压缩(比如gzip)的话,消费者要确保能自动识别压缩类型(默认支持自动识别,但手动配置错误会出问题)。

  • ObjectMapper配置不一致
    如果生产者和消费者用了不同配置的ObjectMapper,也会导致反序列化失败。比如生产者允许忽略未知字段,而消费者的ObjectMapper开启了FAIL_ON_UNKNOWN_PROPERTIES,一旦JSON里有实体类没定义的字段,就会直接报错。
    建议统一配置Spring Kafka使用的ObjectMapper,示例如下:

    @Configuration
    public class KafkaConfig {
        @Bean
        public ObjectMapper kafkaObjectMapper() {
            ObjectMapper mapper = new ObjectMapper();
            // 允许忽略未知字段,避免JSON新增字段导致反序列化失败
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            // 可添加其他配置比如日期格式化、枚举处理等
            return mapper;
        }
    
        @Bean
        public JsonSerializer<YourPayloadClass> jsonSerializer(ObjectMapper kafkaObjectMapper) {
            return new JsonSerializer<>(kafkaObjectMapper);
        }
    
        @Bean
        public JsonDeserializer<YourPayloadClass> jsonDeserializer(ObjectMapper kafkaObjectMapper) {
            JsonDeserializer<YourPayloadClass> deserializer = new JsonDeserializer<>(YourPayloadClass.class);
            deserializer.setObjectMapper(kafkaObjectMapper);
            return deserializer;
        }
    }
    

正确的实体类示例

最后给你一个符合要求的实体类参考,确保注解和JSON键完全对应:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.List;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class FilePayload {
    @JsonProperty("FILE_LIST")
    private List<FileItem> fileList;

    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    public static class FileItem {
        @JsonProperty("KEY1")
        private String key1;

        @JsonProperty("KEY2")
        private String key2;

        @JsonProperty("Key3") // 严格对应JSON里的Key3大小写
        private String key3;

        @JsonProperty("Key4") // 严格对应JSON里的Key4大小写
        private String key4;
    }
}

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

火山引擎 最新活动