Java解析嵌套JSON修改响应结构时出现反序列化错误如何解决?
问题排查与解决方案
核心错误原因
- Key字段类型定义错误:原JSON中
Key是字符串类型,你定义为Map<String,Object>,反序列化时类型不匹配直接抛出异常 - POJO层级逻辑错误:
practice是subRecords下每个元素的row数组内的属性,你将Key、practice、subRecords平级放在根POJO中,完全不符合原JSON的嵌套结构 - Setter逻辑错误:
setSubRecords方法直接从row.get(0)取practice,但subRecords列表的每个元素的属性是row和Key,不存在直接的practice属性,取值为null+强制类型转换会触发ClassCastException
修复方案(基于Jackson)
方案1:先反序列化原始结构再转换为目标结构(更稳定,易维护)
第一步:定义原始JSON对应的POJO
// 根节点 @Getter @Setter @JsonInclude(JsonInclude.Include.NON_NULL) public class OriginalRoot { private List<OriginalSubRecord> subRecords; } // OriginalSubRecord对应原subRecords数组的元素 @Getter @Setter public class OriginalSubRecord { private String Key; private List<OriginalRowItem> row; } // OriginalRowItem对应row数组的元素 @Getter @Setter public class OriginalRowItem { private List<PracticeItem> practice; } // practice数组的元素 @Getter @Setter public class PracticeItem { private String addressId; private String name; }
第二步:定义目标结构POJO
// 目标根节点 @Getter @Setter @JsonInclude(JsonInclude.Include.NON_NULL) public class TargetRoot { private List<TargetSubRecord> subRecords; } // 目标subRecords元素,去掉row层 @Getter @Setter public class TargetSubRecord { private String Key; private List<PracticeItem> practice; }
第三步:结构转换逻辑
public TargetRoot convert(OriginalRoot original) { TargetRoot target = new TargetRoot(); List<TargetSubRecord> targetSubRecords = original.getSubRecords().stream() .map(originalSub -> { TargetSubRecord targetSub = new TargetSubRecord(); targetSub.setKey(originalSub.getKey()); // 取row数组第一个元素的practice,和你的需求一致 if (originalSub.getRow() != null && !originalSub.getRow().isEmpty()) { targetSub.setPractice(originalSub.getRow().get(0).getPractice()); } return targetSub; }) .toList(); target.setSubRecords(targetSubRecords); return target; }
方案2:用@JsonSetter直接在目标POJO中处理嵌套(省略中间POJO)
@Getter @Setter @JsonInclude(JsonInclude.Include.NON_NULL) public class TargetRoot { private List<TargetSubRecord> subRecords; } @Getter @JsonInclude(JsonInclude.Include.NON_NULL) public class TargetSubRecord { private String Key; private List<PracticeItem> practice; // 自定义处理row字段的反序列化 @JsonSetter("row") public void setRow(List<Map<String, Object>> row) { if (row != null && !row.isEmpty()) { Object practiceObj = row.get(0).get("practice"); if (practiceObj instanceof List) { // 用ObjectMapper转换避免强制转换异常 ObjectMapper mapper = new ObjectMapper(); this.practice = mapper.convertValue(practiceObj, new TypeReference<List<PracticeItem>>() {}); } } } }
额外注意事项
- 所有类型转换前必须做非空和类型校验,避免空指针和类型转换异常
- 不要滥用
Map<String,Object>作为POJO属性类型,明确的字段定义可以提前暴露类型不匹配问题,减少运行时错误
内容的提问来源于stack exchange,提问作者Jon Abraham
相关产品推荐
相关产品推荐

