如何将含sku0、sku1等动态字段的JSON映射为Java POJO?
解决动态字段JSON到Java POJO的映射问题
错误原因
你的报错核心是把JSON中的单个对象(sku0是一个Object)当成了List类型反序列化。原SkuInventory类里定义了private List<Sku0> sku0;,但API返回的sku0是单个对象而非数组,Jackson无法将Object转成ArrayList,因此抛出异常。同时,sku0、sku1这类是动态键,用固定字段名无法适配所有动态sku条目。
正确解决方案
1. 修改SkuInventory类,用Map接收动态sku字段
把SkuInventory改成用Map<String, Sku>存储所有动态sku条目,每个sku键(sku0、sku1...)对应的值都是Sku类型对象:
public class SkuInventory { // 动态存储所有sku键值对,键为sku0/sku1等字符串,值为对应Sku对象 @JsonAnyGetter @JsonAnySetter private Map<String, Sku> skuMap = new HashMap<>(); public Map<String, Sku> getSkuMap() { return skuMap; } public void setSkuMap(Map<String, Sku> skuMap) { this.skuMap = skuMap; } }
@JsonAnySetter注解会让Jackson自动把所有未匹配到固定字段的键值对存入该Map,完美适配动态键场景;@JsonAnyGetter则保证序列化时能正常输出这些动态字段。
2. 修正Root类关联
确保Root类的skuInventory字段类型为修改后的SkuInventory:
public class Root { private SkuInventory skuInventory; public SkuInventory getSkuInventory() { return skuInventory; } public void setSkuInventory(SkuInventory skuInventory) { this.skuInventory = skuInventory; } }
3. 调整反序列化后的取值逻辑
原代码中getSku()方法不存在,现在通过Map获取对应sku:
ResponseEntity<?> inventoryData = (ResponseEntity<?>) inventoryAPIResponse.getData(); Map<?, ?> inventoryBody = (Map<?, ?>) inventoryData.getBody(); Root atgInventory = getObjectMapper().convertValue(inventoryBody, Root.class); // 获取所有sku条目 Map<String, Sku> allSkus = atgInventory.getSkuInventory().getSkuMap(); // 示例:获取sku0对应的对象 Sku sku0 = allSkus.get("sku0"); // 遍历所有sku for (Map.Entry<String, Sku> entry : allSkus.entrySet()) { String skuKey = entry.getKey(); // 如sku0、sku1 Sku skuValue = entry.getValue(); // 处理单个sku的业务逻辑 }
4. 补充注意事项
- 原代码中的
Sku0类需和你定义的Sku类统一,避免类名混淆。 Inventory类中的Time类需适配{"time": 1674363600000}结构,示例定义:
public class Time { private long time; public long getTime() { return time; } public void setTime(long time) { this.time = time; } }
内容的提问来源于stack exchange,提问作者Sanjay Naik
相关产品推荐
相关产品推荐

