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

Java读取含重复键JSON文件仅返回最后值,求获取全部对象的代码

问题分析

你提供的JSON格式不合法——JSON对象中不允许存在重复键(这里statements重复出现),标准JSON解析器默认只会保留最后一个重复键的对应值,这就是你只能读到最后一组数据的原因。

解决方案

方案1:修复JSON为合法格式(推荐)

先把JSON调整为标准结构,将多个statements数组合并成一个:

{
  "statements": [
    {
      "kpCustomLevel": {
        "region": "KNW",
        "statementType": "Medical",
        "coverageType": "DHMO"
      }
    },
    {
      "kpCustomLevel": {
        "region": "KNP",
        "statementType": "Medical1",
        "coverageType": "DHMN"
      }
    }
  ]
}

之后用Jackson或Gson等主流JSON库解析成Java对象数组即可。

步骤1:定义对应Java实体类

// KpCustomLevel.java
public class KpCustomLevel {
    private String region;
    private String statementType;
    private String coverageType;

    // 无参构造、全参构造
    public KpCustomLevel() {}
    public KpCustomLevel(String region, String statementType, String coverageType) {
        this.region = region;
        this.statementType = statementType;
        this.coverageType = coverageType;
    }

    // getter和setter方法
    public String getRegion() { return region; }
    public void setRegion(String region) { this.region = region; }
    public String getStatementType() { return statementType; }
    public void setStatementType(String statementType) { this.statementType = statementType; }
    public String getCoverageType() { return coverageType; }
    public void setCoverageType(String coverageType) { this.coverageType = coverageType; }
}
// Statement.java
public class Statement {
    private KpCustomLevel kpCustomLevel;

    public Statement() {}
    public Statement(KpCustomLevel kpCustomLevel) {
        this.kpCustomLevel = kpCustomLevel;
    }

    public KpCustomLevel getKpCustomLevel() { return kpCustomLevel; }
    public void setKpCustomLevel(KpCustomLevel kpCustomLevel) { this.kpCustomLevel = kpCustomLevel; }
}
// StatementsWrapper.java
public class StatementsWrapper {
    private List<Statement> statements;

    public StatementsWrapper() {}
    public StatementsWrapper(List<Statement> statements) {
        this.statements = statements;
    }

    public List<Statement> getStatements() { return statements; }
    public void setStatements(List<Statement> statements) { this.statements = statements; }
}

步骤2:用Jackson解析到数组

先添加Jackson依赖(Maven示例):

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 使用最新稳定版即可 -->
</dependency>

解析代码:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class JsonParser {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 读取JSON文件并映射到Wrapper类
            StatementsWrapper wrapper = objectMapper.readValue(new File("your-json-file.json"), StatementsWrapper.class);
            // 将List转为数组
            Statement[] statementsArray = wrapper.getStatements().toArray(new Statement[0]);
            
            // 测试输出验证结果
            for (Statement stmt : statementsArray) {
                KpCustomLevel level = stmt.getKpCustomLevel();
                System.out.printf("Region: %s, StatementType: %s, CoverageType: %s%n",
                        level.getRegion(), level.getStatementType(), level.getCoverageType());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方案2:无法修改原始JSON时的兼容处理

如果没办法调整原始非法JSON,可以用Jackson自定义反序列化逻辑处理重复键:

自定义重复键反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DuplicateKeyDeserializer extends JsonDeserializer<List<Statement>> {
    @Override
    public List<Statement> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        List<Statement> statements = new ArrayList<>();
        ObjectMapper mapper = (ObjectMapper) p.getCodec();
        
        while (p.nextToken() != JsonToken.END_OBJECT) {
            String fieldName = p.getCurrentName();
            if ("statements".equals(fieldName)) {
                p.nextToken();
                // 读取当前statements数组并合并到总列表
                List<Statement> currentBatch = mapper.readValue(p, List.class);
                statements.addAll(currentBatch);
            } else {
                // 跳过无关字段
                p.skipChildren();
            }
        }
        return statements;
    }
}

解析实现代码

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class DuplicateKeyJsonParser {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        // 允许单个值被解析为数组(兼容数组只有一个元素的情况)
        objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
        
        // 注册自定义反序列化器
        SimpleModule module = new SimpleModule();
        module.addDeserializer(List.class, new DuplicateKeyDeserializer());
        objectMapper.registerModule(module);
        
        try {
            // 直接读取非法JSON并解析为Statement列表
            List<Statement> statementsList = objectMapper.readValue(new File("invalid-json-file.json"), List.class);
            // 转为数组
            Statement[] statementsArray = statementsList.toArray(new Statement[0]);
            
            // 测试输出
            for (Statement stmt : statementsArray) {
                KpCustomLevel level = stmt.getKpCustomLevel();
                System.out.printf("Region: %s, StatementType: %s, CoverageType: %s%n",
                        level.getRegion(), level.getStatementType(), level.getCoverageType());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
注意事项
  • 优先选择方案1,非法JSON在不同解析器下的行为存在差异,兼容性无法保障。
  • 若使用Gson库,逻辑类似:合法JSON直接映射实体类;非法JSON需自定义TypeAdapter处理重复键。

内容的提问来源于stack exchange,提问作者Neeraj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:35:41