Java向Kafka Topic发送JSON问题:值带多余引号
解决Kafka消息值被额外引号包裹的问题
你遇到的额外引号问题,本质是消息被双重序列化了——要么是你先把对象转成了JSON字符串,又被Kafka序列化器再次处理;要么是序列化器配置/使用方式不对,把JSON结构当成普通字符串序列化了。下面针对你用的两种实现方式,分别给出解决办法:
方案1:正确使用JsonSerializer发送JsonNode
如果用JsonSerializer,直接传递JsonNode对象即可,不要先把JsonNode转成JSON字符串再发送(否则JsonSerializer会把这个字符串当成普通Java对象序列化,导致外层多一层引号)。
示例代码:
// 配置Producer Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "your-broker-address:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); // 核心:指定值序列化器为JsonSerializer props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class.getName()); ObjectMapper objectMapper = new ObjectMapper(); KafkaProducer<String, JsonNode> producer = new KafkaProducer<>(props); // 直接构建或转换得到JsonNode JsonNode payload = objectMapper.createObjectNode().put("theKey", "theValue"); // 发送消息:直接传JsonNode,不要转成String ProducerRecord<String, JsonNode> record = new ProducerRecord<>("your-topic-name", payload); producer.send(record); producer.close();
方案2:用ByteArraySerializer发送POJO序列化的字节数组
如果选择这种方式,直接将POJO序列化为字节数组,不要先转成JSON字符串再转字节数组——后者本质是把字符串的字节发送给Kafka,Lenses会识别为字符串类型,自然显示带引号的内容。
示例代码:
// 配置Producer Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "your-broker-address:9092"); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName()); // 使用ByteArraySerializer作为值序列化器 props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName()); ObjectMapper objectMapper = new ObjectMapper(); KafkaProducer<String, byte[]> producer = new KafkaProducer<>(props); // 直接将POJO序列化为字节数组 YourPojo pojo = new YourPojo("theValue"); // 你的业务POJO类 byte[] jsonBytes = objectMapper.writeValueAsBytes(pojo); // 发送字节数组 ProducerRecord<String, byte[]> record = new ProducerRecord<>("your-topic-name", jsonBytes); producer.send(record); producer.close();
常见错误排查
- 避免双重序列化:不要先把对象转成JSON字符串,再用
JsonSerializer或ByteArraySerializer发送——这会让Kafka把字符串当成原始数据处理,导致外层加引号。 - 检查序列化器配置:确保
value.serializer配置的是你预期的序列化器,不要混用(比如本来想发JsonNode,却配了StringSerializer)。 - Lenses显示验证:如果确认消息本身是正确的JSON字节,可检查Lenses的消息解析设置,确保它用JSON格式解析值,而不是默认的字符串格式。
内容的提问来源于stack exchange,提问作者jkim
相关产品推荐
相关产品推荐

