如何用JsonNode将嵌套JSON的字段名和值存入List<String>
提取JSON带层级路径的字段名及对应值
需求说明
给定如下嵌套结构的JSON:
{ "contact_info": [{ "contact_id": "Contact_001", "contact_status": { "exam_status": 0, "term_list": [{ "term_code": 110, "t_list": [{ "s_code": "12001", "sexam_status": 0 }, { "s_code": "13001", "sexam_status": 1 } ] }] } }] }
需要将所有字段的带层级归属的路径(例如contact_status.term_list[0].t_list[0].s_code)和对应值组合成字符串,存入List<String>。
原代码仅返回单独的字段名,无法满足需求,以下是修正方案:
原代码问题分析
- 递归方法未传递当前路径前缀,无法构建完整的层级路径
- 仅收集字段名,未将字段名与对应值组合存储
修正后的代码
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; public class JsonPathExtractor { public static List<String> getPathAndValuesFromJson(String json) throws Exception { ObjectMapper mapper = new ObjectMapper(); List<String> result = new ArrayList<>(); JsonNode jsonNode = mapper.readTree(json); // 初始调用时路径为空字符串 traverseJsonNode(jsonNode, "", result); return result; } private static void traverseJsonNode(JsonNode jsonNode, String currentPath, List<String> result) { if (jsonNode.isObject()) { Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields(); fields.forEachRemaining(field -> { String fieldName = field.getKey(); // 拼接当前字段到路径:根节点直接用字段名,非根节点加.分隔 String newPath = currentPath.isEmpty() ? fieldName : currentPath + "." + fieldName; traverseJsonNode(field.getValue(), newPath, result); }); } else if (jsonNode.isArray()) { ArrayNode arrayNode = (ArrayNode) jsonNode; // 遍历数组元素,添加[index]标识到路径 for (int i = 0; i < arrayNode.size(); i++) { String newPath = currentPath + "[" + i + "]"; traverseJsonNode(arrayNode.get(i), newPath, result); } } else { // 叶子节点:拼接路径与值,存入结果列表 String entry = currentPath + " = " + jsonNode.asText(); result.add(entry); } } // 测试示例 public static void main(String[] args) throws Exception { String json = "{\n" + " \"contact_info\": [{\n" + " \"contact_id\": \"Contact_001\",\n" + " \"contact_status\": {\n" + " \"exam_status\": 0,\n" + " \"term_list\": [{\n" + " \"term_code\": 110,\n" + " \"t_list\": [{\n" + " \"s_code\": \"12001\",\n" + " \"sexam_status\": 0\n" + " },\n" + " {\n" + " \"s_code\": \"13001\",\n" + " \"sexam_status\": 1\n" + " }\n" + " ]\n" + " }]\n" + " }\n" + " }]\n" + "}"; List<String> pathValues = getPathAndValuesFromJson(json); pathValues.forEach(System.out::println); } }
关键修改点说明
- 新增
currentPath参数:递归过程中持续跟踪当前节点的完整路径 - 对象节点处理:用
.拼接父路径与当前字段名,保证层级连贯性 - 数组节点处理:添加
[索引]标识数组元素的位置,区分同数组内的不同元素 - 叶子节点处理:将完整路径与对应值组合成指定格式的字符串,存入结果列表
运行结果示例
执行上述代码后,List中的元素如下:
contact_info[0].contact_id = Contact_001 contact_info[0].contact_status.exam_status = 0 contact_info[0].contact_status.term_list[0].term_code = 110 contact_info[0].contact_status.term_list[0].t_list[0].s_code = 12001 contact_info[0].contact_status.term_list[0].t_list[0].sexam_status = 0 contact_info[0].contact_status.term_list[0].t_list[1].s_code = 13001 contact_info[0].contact_status.term_list[0].t_list[1].sexam_status = 1
内容的提问来源于stack exchange,提问作者TaraNG
相关产品推荐
相关产品推荐

