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

使用Jackson ObjectMapper处理嵌套Avro对象转JSON异常的方案问询

解决Jackson ObjectMapper转换嵌套Avro对象为JSON的异常问题

问题场景

给定JSON Payload:

{"tradeQuantity":13,"tradeMarket":"sssss","stockName":"teststock","tradeType":"testtype","price":12.2,"amount":12.5,"address":{"stret" : "aaa","city"  : "bbb" }}

Avro类实例化代码:

StockHistory stockHistory= new StockHistory();
stockHistory.setStockName(model.getStockName());
stockHistory.setTradeType(model.getTradeType());
stockHistory.setPrice(model.getPrice());
stockHistory.setAmount(model.getAmount());
stockHistory.setTradeId(new Random(1000).nextInt());
stockHistory.setTradeMarket(model.getTradeMarket());
stockHistory.setTradeQuantity(model.getTradeQuantity());

Address address = new Address();
address.setCity("sss");
address.setStreetaddress("aaaa");
stockHistory.setAddress(address);

使用普通Jackson ObjectMapper转换时:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(StockHistory.class, IgnoreSchemaProperty.class);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

仅当StockHistory无嵌套Address时转换正常,包含嵌套对象时抛出异常:

org.apache.avro.AvroRuntimeException: Not an array: {"type":"record","name":"Address","namespace":"com.spring.cloud.streams.avro","fields":[{"name":"streetaddress","type":["null","string"],"default":null},{"name":"city","type":["null","string"],"default":null}]}

解决方案

使用Jackson官方提供的Avro数据格式模块(jackson-dataformat-avro),它专门适配Avro生成的类,能正确处理嵌套Avro对象的序列化/反序列化。

步骤1:引入依赖

如果使用Maven,在pom.xml中添加:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-avro</artifactId>
    <version>2.15.2</version> <!-- 版本需与你的Jackson核心版本保持一致 -->
</dependency>

步骤2:替换ObjectMapper为AvroMapper

修改代码,用AvroMapper替代普通ObjectMapper:

import com.fasterxml.jackson.dataformat.avro.AvroMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;

// 创建Avro专用的Mapper实例
AvroMapper mapper = new AvroMapper();
mapper.addMixIn(StockHistory.class, IgnoreSchemaProperty.class);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

// 序列化Avro对象到JSON
String jsonOutput = mapper.writeValueAsString(stockHistory);

// 从JSON反序列化回Avro对象
StockHistory parsedHistory = mapper.readValue(jsonOutput, StockHistory.class);

原因分析

普通ObjectMapper未针对Avro生成类的特殊结构做适配,Avro类内部包含schema相关属性,处理嵌套对象时,Jackson默认的反射逻辑会触发Avro内部校验,导致类型错误。而AvroMapper专门针对Avro的record结构、嵌套类型做了适配,能正确识别并处理嵌套Avro对象。

Google GSON能正常运行是因为其默认字段遍历逻辑更宽松,自动跳过了Avro内部的schema字段,未触发校验,但这种方式无Avro专属适配,长期稳定性不如官方模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:05:20