访问嵌套JSON作为AWS DynamoDB主键时遇空指针异常求助
解决DynamoDB存储嵌套JSON时的NullPointerException问题
首先,我们来拆解你代码里的核心问题:
1. JSON节点遍历逻辑错误
你的根JSON节点是{"api": {...}},当你用rootNode.iterator()时,遍历的是根节点的直接子节点——也就是仅"api"这一个节点。之后你又调用currentNode.path("api"),相当于在已经是api的节点里再找api,这会返回一个MissingNode(不存在的节点),后续基于这个节点的操作自然会因为找不到正确路径而抛出空指针。
2. Fixtures是数组,不能直接提取单个字段
api下的fixtures是一个数组(即使只有一个元素),你直接用findValue("fixture_id")是无法从数组里拿到对应值的,必须遍历数组里的每个对象元素。
3. 潜在的字段缺失问题
你代码里尝试获取的league_id在你提供的示例JSON中并不存在,这也会导致后续操作报错,需要确认这个字段是否是API返回的可选字段,或者是否有路径错误。
修正后的代码示例
JsonParser parser = new JsonFactory().createParser(new File("fixturesTwo.json")); JsonNode rootNode = new ObjectMapper().readTree(parser); // 正确获取api节点 JsonNode apiNode = rootNode.get("api"); if (apiNode == null) { System.err.println("API node not found in JSON"); parser.close(); return; } // 获取fixtures数组 JsonNode fixturesArray = apiNode.get("fixtures"); if (fixturesArray == null || !fixturesArray.isArray()) { System.err.println("Fixtures array not found or invalid"); parser.close(); return; } // 遍历每个fixture对象 for (JsonNode fixtureNode : fixturesArray) { // 安全获取fixture_id,避免空指针 int fixtureId = fixtureNode.path("fixture_id").asInt(-1); if (fixtureId == -1) { System.err.println("Skipping fixture: fixture_id missing"); continue; } // 注意:示例JSON中没有league_id,这里先处理为可选字段,根据实际情况调整 int leagueId = fixtureNode.path("league_id").asInt(-1); if (leagueId == -1) { System.err.println("Skipping fixture: league_id missing"); continue; } // 获取主队和客队名称 JsonNode homeTeamNode = fixtureNode.path("homeTeam"); String homeTeamName = homeTeamNode.path("team_name").asText("Unknown Home Team"); JsonNode awayTeamNode = fixtureNode.path("awayTeam"); String awayTeamName = awayTeamNode.path("team_name").asText("Unknown Away Team"); try { table.putItem(new Item() .withPrimaryKey("fixture_id", fixtureId, "league_id", leagueId) .withString("Home Team", homeTeamName) .withString("Away Team", awayTeamName)); System.out.println("PutItem succeeded: " + fixtureId + " " + leagueId); } catch (Exception e) { System.err.println("Unable to add fixture: " + fixtureId); System.err.println(e.getMessage()); // 这里建议continue而不是break,避免一个错误导致所有后续操作终止 continue; } } parser.close();
关键优化点
- 使用
get()获取核心节点并做非空检查,避免后续空指针 - 遍历
fixtures数组的每个元素,而不是直接从数组节点提取字段 - 用
path()替代直接取值,配合默认值(如asInt(-1)、asText("Unknown"))处理字段缺失的情况 - 把
withJSON()改为withString(),因为你存储的是球队名称字符串,不是JSON对象 - 错误处理改为
continue,单个fixture的错误不会中断整个遍历流程
内容的提问来源于stack exchange,提问作者Deane Kane
相关产品推荐
相关产品推荐

