
json 规范要求对象内键名必须唯一,若文件中出现多个同名键(如重复的 "statements"),标准解析器将仅保留最后一个值;本文详解如何识别该问题、修复 json 结构,并使用 java(jackson)安全读取全部嵌套对象。
json 规范要求对象内键名必须唯一,若文件中出现多个同名键(如重复的 "statements"),标准解析器将仅保留最后一个值;本文详解如何识别该问题、修复 json 结构,并使用 java(jackson)安全读取全部嵌套对象。
在实际开发中,你遇到的 "statements" 键重复问题并非数据内容重复,而是违反 JSON 语法规范:一个 JSON 对象({...})中不允许存在两个相同名称的键。你提供的原始片段实质上是无效 JSON:
{
"statements": [ { "kpCustomLevel": { "region": "KNW", ... } } ],
"statements": [ { "kpCustomLevel": { "region": "KNP", ... } } ]
}
上述结构在语法上不合法——主流 JSON 解析器(如 Jackson、Gson)会静默忽略前一个 "statements",仅保留后者,导致“只读到一条记录”。
✅ 正确的 JSON 格式应将所有 statement 合并为单个数组:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
{
"statements": [
{
"kpCustomLevel": {
"region": "KNW",
"statementType": "Medical",
"coverageType": "DHMO"
}
},
{
"kpCustomLevel": {
"region": "KNP",
"statementType": "Medical1",
"coverageType": "DHMN"
}
}
]
}
使用 Jackson 完整读取示例(Java)
假设已修正 JSON 文件为合法格式,推荐使用 Jackson 的 ObjectMapper 进行类型安全解析:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.List;
// 内部数据类(建议使用 record 提升简洁性,此处用 class 兼容性更广)
class KpCustomLevel {
private String region;
private String statementType;
private String coverageType;
// 构造函数、getter 省略,或使用 Lombok @Data
}
class Statement {
@JsonProperty("kpCustomLevel")
private KpCustomLevel kpCustomLevel;
// getter 方法
public KpCustomLevel getKpCustomLevel() { return kpCustomLevel; }
}
class Root {
private List<statement> statements;
public List<statement> getStatements() { return statements; }
}
// 解析逻辑
public class JsonReader {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Root root = mapper.readValue(new File("data.json"), Root.class);
System.out.println("共读取 " + root.getStatements().size() + " 条 statements");
for (int i = 0; i <h3>关键注意事项</h3>
<ul>
<li>? <strong>切勿尝试“强制解析非法 JSON”</strong>:某些库(如 org.json)虽允许宽松模式,但行为不可靠,易引发隐性 Bug;</li>
<li>✅ <strong>源头治理优先</strong>:联系数据提供方修正 JSON 输出逻辑,确保 "statements" 为单一数组字段;</li>
<li>⚠️ 若无法修改源文件,可先用正则或文本预处理(如合并重复键),但属临时方案,不推荐用于生产环境;</li>
<li>? 使用 List<statement> 而非数组(Statement[]),更符合 Java 集合惯用法,支持动态扩容与流式操作。</statement>
</li>
</ul>
<p>通过遵循 JSON 标准并采用强类型绑定,你不仅能完整获取全部 statements,还能获得编译期校验、IDE 自动补全和序列化/反序列化一致性保障。</p></statement></statement>










