Jackson嵌套对象反序列化问题:POJO映射返回空对象
解决JSON反序列化时POJO字段为null的问题
别急,完全不用写自定义JsonDeserializer!问题出在你没正确处理JSON的层级结构——你的Product类标注了@JsonRootName("data"),但整个JSON的根节点是包含info和data的外层对象,Jackson默认会从根节点开始解析,而@JsonRootName的作用是当JSON的根节点名称和POJO的根名称匹配时才会自动展开,显然这里不匹配,所以才会得到空对象。
给你两种简单的解决方案:
方案一:创建外层包装类(最直观)
直接定义一个对应整个JSON结构的包装类,把Product作为它的一个字段:
// 对应整个JSON响应的外层类 public class ApiResponse { private String info; private Product data; // 记得添加getter和setter,或者让Jackson能访问字段(比如设置为public) public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public Product getData() { return data; } public void setData(Product data) { this.data = data; } } // 你的原Product类,不需要@JsonRootName了 public class Product { private String id; private List<Car> cars; // getter和setter public String getId() { return id; } public void setId(String id) { this.id = id; } public List<Car> getCars() { return cars; } public void setCars(List<Car> cars) { this.cars = cars; } } public class Car { private String id; // getter和setter public String getId() { return id; } public void setId(String id) { this.id = id; } }
解析的时候直接用ApiResponse作为目标类型,之后取出data字段就是你要的Product对象:
ObjectMapper mapper = new ObjectMapper(); ApiResponse response = mapper.readValue(jsonString, ApiResponse.class); Product product = response.getData(); // 现在product的id和cars就有值了
方案二:先解析为JsonNode再提取目标节点(不用新增类)
如果不想写包装类,可以先把JSON解析成JsonNode,提取出data节点后再反序列化成Product:
ObjectMapper mapper = new ObjectMapper(); // 先读整个JSON为JsonNode JsonNode rootNode = mapper.readTree(jsonString); // 提取data节点 JsonNode dataNode = rootNode.get("data"); // 把data节点反序列化为Product Product product = mapper.treeToValue(dataNode, Product.class);
额外注意点
别忘了确保你的POJO字段能被Jackson访问到:
- 要么给字段添加
getter和setter方法(Jackson默认通过这些方法读写字段) - 要么把字段设为
public - 或者配置ObjectMapper允许访问私有字段:
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
这样处理后,你就能正常拿到非空的Product对象了,完全不需要自定义反序列化器~
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

