如何在不创建任何List的前提下从嵌套JSON结构中提取JSON参数
无List结构约束下的嵌套JSON参数提取实现方案
核心破局逻辑
很多实现误区是遇到JSON数组就必须将其反序列化为List结构才能取数,实际上主流JSON解析框架都支持树模型路径直取能力,遇到数组节点时直接通过下标索引定位元素,全程不需要实例化List对象,完全符合约束要求。
待解析目标JSON
{ "response": { "id": "4234242424424244", "phone": "", "details": "OPT_IN", "status": "success" }, "data": { "response_messages": [ { "id": "312", "phone": "91XXXXXXXXXXX", "details": "You are already opted In.", "status": "error" } ] } }
可落地实现代码
基于Jackson JsonNode的实现
全程不执行POJO映射、不创建List实例,通过树路径直接定位节点取值:
// 初始化Jackson对象映射器 ObjectMapper objectMapper = new ObjectMapper(); // 将JSON解析为节点树,不做任何类型绑定 JsonNode rootNode = objectMapper.readTree(rawJsonString); // 直取顶层response节点下的参数 String topResponseId = rootNode.at("/response/id").asText(); String topOptFlag = rootNode.at("/response/details").asText(); String topStatus = rootNode.at("/response/status").asText(); // 直取数组下标0的消息节点参数,无需将数组转List String subMsgId = rootNode.at("/data/response_messages/0/id").asText(); String subPhone = rootNode.at("/data/response_messages/0/phone").asText(); String subErrMsg = rootNode.at("/data/response_messages/0/details").asText(); String subStatus = rootNode.at("/data/response_messages/0/status").asText();
合规性说明:
at()方法解析路径时,遇到数组类型节点会直接将路径中的数字段作为下标索引匹配子节点,整个过程没有创建ArrayList、LinkedList等任何List结构实例,完全满足约束。
基于Fastjson的实现
不调用数组转List的API,通过框架内置的数组节点下标方法取值:
// 将JSON解析为根对象,不触发数组反序列化为List的逻辑 JSONObject rootObj = JSON.parseObject(rawJsonString); // 逐层定位节点取顶层参数 JSONObject topRespNode = rootObj.getJSONObject("response"); String topResponseId = topRespNode.getString("id"); String topOptFlag = topRespNode.getString("details"); // 直接通过数组节点的下标方法取第0个元素,不将数组转为List JSONArray msgArray = rootObj.getJSONObject("data").getJSONArray("response_messages"); JSONObject firstMsgNode = msgArray.getJSONObject(0); String subPhone = firstMsgNode.getString("phone"); String subErrMsg = firstMsgNode.getString("details");
避坑注意点
- 绝对不要在取值过程中调用
toJavaList()、stream().collect(Collectors.toList())这类会生成List实例的API,直接用节点自带的下标方法取数即可 - 当前场景下
response_messages数组固定只有1个元素,不需要做数组遍历、不需要循环取数,直接定位下标0的节点即可拿到全部目标值,从根源上避免List结构的引入 - 加边界判断时只需要判断目标节点是否存在,不需要把数组内容加载到List中做二次处理
内容的提问来源于stack exchange,提问作者Babbal Kumar
相关产品推荐
相关产品推荐

