本文介绍如何使用 jackson 库将嵌套 json 结构(含数组与对象)精准反序列化为结构清晰、支持 getter/setter 访问的 java 实体类,替代原始 map 方式,提升代码可维护性与类型安全性。
在实际开发中,直接将 JSON 解析为 Map(如 GSON 的 TypeToken 方式)虽能快速读取数据,但缺乏编译期类型检查、无法直接调用属性方法、难以进行字段级编辑或校验,且嵌套结构(如 systems 数组中的对象列表)访问繁琐易错。更专业、可持续的方案是基于 JSON 结构定义强类型的 Java Bean 类,并借助成熟的序列化库完成双向映射。
推荐使用 Jackson Databind(比 GSON 更广泛用于 Spring 生态,对泛型、嵌套集合支持更稳健)。首先,根据提供的 JSON 结构创建两个对应类:
// 主配置类,对应顶层 JSON 对象
public class AppInventory {
private String title;
private String description;
private List systems;
// 构造函数(可选)
public AppInventory() {}
// Getter 和 Setter 方法(务必完整实现,否则 Jackson 反序列化失败)
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public List getSystems() { return systems; }
public void setSystems(List systems) { this.systems = systems; }
}
// 嵌套系统信息类,对应 "systems" 数组中的每个对象
public class SystemInfo {
private String name;
private String purpose;
private String owner;
private List subOwner; // 注意:JSON 中键名为 "sub_owner",Java 属性名可小写驼峰
private String location;
private String tag;
// Getter 和 Setter(同上,必须提供)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPurpose() { return purpose; }
public void setPurpose(String purpose) { this.purpose = purpose; }
public String getOwner() { return owner; }
public void setOwner(String owner) { this.owner = owner; }
public List getSubOwner() { return subOwner; }
public void setSubOwner(List subOwner) { this.subOwner = subOwner; }
public String getLocation() { return location; }
public void setLocation(String location) { this.location = location; }
public String getTag() { return tag; }
public void setTag(String tag) { this.tag = tag; }
}
✅ 关键注意事项:Jackson 默认按 Java Bean 约定(getter/setter) 匹配字段,不依赖 @JsonProperty 注解即可工作;若 JSON 键名与 Java 属性名不一致(如 “sub_owner” → subOwner),Jackson 默认启用 SNAKE_CASE 或 LOWER_CAMEL_CASE 自动映射(2.12+ 版本默认支持下划线转驼峰);所有字段的 setter 方法必须存在,否则反序列化时该字段将为 null;使用 List 而非原始数组,便于后续增删改查操作;若需兼容旧版 Jackson 或自定义命名策略,可在 ObjectMapper 中配置:ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
接下来,执行反序列化并访问/修改数据: