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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:36:04