如何遍历JsonNode对象的所有子节点并提取price字段明细信息
实现方案
以下针对Jackson框架下JsonNode节点遍历提取price明细的需求,提供两种适配不同场景的实现方式:
场景1:已知JSON结构,精准提取(性能最优,推荐)
你提供的响应报文结构固定,可直接按层级定位到商品集合节点遍历,代码实现如下:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; // 定义Price明细存储类 class PriceDetail { private String itemId; private Double amount; private Double baseAmount; public PriceDetail(String itemId, Double amount, Double baseAmount) { this.itemId = itemId; this.amount = amount; this.baseAmount = baseAmount; } // 按需补充getter、setter方法 } public class ExtractPriceDemo { public static void main(String[] args) throws Exception { // 这里替换为你的实际响应报文字符串 String response = "{\n \"content\": {\n \"cart\": {\n \"logs\": {\n \"logs_cart_100\": {\n \"method\": \"over\",\n \"items\": {\n \"111\": {\n \"firstName\": \"Ram\",\n \"lastName\": \"K\",\n \"price\": {\n \"amount\": 100.0,\n \"baseAmount\": 100.0\n }\n },\n \"222\": {\n \"firstName\": \"Velvan\",\n \"lastName\": \"S\",\n \"price\": {\n \"amount\": 200.0,\n \"baseAmount\": 200.0\n }\n },\n \"333\": {\n \"firstName\": \"Dinesh\",\n \"lastName\": \"M\",\n \"price\": {\n \"amount\": 300.0,\n \"baseAmount\": 300.0\n }\n }\n }\n }\n },\n \"promotions\": [\n {\n \"promotionName\": \"Dummy-1\"\n },\n {\n \"promotionName\": \"Dummy-2\"\n },\n {\n \"promotionName\": \"Dummy-3\"\n }\n ]\n }\n }\n}"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readValue(response, JsonNode.class); List<PriceDetail> priceList = new ArrayList<>(); // 按层级定位到商品集合节点 JsonNode itemsNode = actualObj.get("content") .get("cart") .get("logs") .get("logs_cart_100") .get("items"); // 遍历所有商品节点提取price信息 Iterator<Map.Entry<String, JsonNode>> itemsIterator = itemsNode.fields(); while (itemsIterator.hasNext()) { Map.Entry<String, JsonNode> entry = itemsIterator.next(); String itemId = entry.getKey(); JsonNode priceNode = entry.getValue().get("price"); Double amount = priceNode.get("amount").asDouble(); Double baseAmount = priceNode.get("baseAmount").asDouble(); priceList.add(new PriceDetail(itemId, amount, baseAmount)); } // 验证输出结果 for (PriceDetail detail : priceList) { System.out.printf("商品ID:%s,支付金额:%.2f,基准金额:%.2f%n", detail.getItemId(), detail.getAmount(), detail.getBaseAmount()); } } }
场景2:未知JSON结构,全节点递归匹配提取
如果后续JSON结构会变动,可通过递归遍历所有节点匹配price字段提取,代码实现如下:
// 递归遍历节点方法 public static void traverseAllNode(JsonNode node, List<PriceDetail> priceList, String currentItemId) { if (node.isObject()) { Iterator<Map.Entry<String, JsonNode>> fields = node.fields(); while (fields.hasNext()) { Map.Entry<String, JsonNode> field = fields.next(); String fieldName = field.getKey(); JsonNode fieldValue = field.getValue(); if ("price".equals(fieldName)) { // 匹配到price字段直接提取 Double amount = fieldValue.get("amount").asDouble(); Double baseAmount = fieldValue.get("baseAmount").asDouble(); priceList.add(new PriceDetail(currentItemId, amount, baseAmount)); } else { // 记录当前商品ID供提取price时使用 String newItemId = currentItemId; if (fieldName.matches("\\d+")) { newItemId = fieldName; } traverseAllNode(fieldValue, priceList, newItemId); } } } else if (node.isArray()) { for (JsonNode arrayItem : node) { traverseAllNode(arrayItem, priceList, currentItemId); } } } // 调用方式 public static void main(String[] args) throws Exception { String response = "你的实际响应报文"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readValue(response, JsonNode.class); List<PriceDetail> priceList = new ArrayList<>(); traverseAllNode(actualObj, priceList, null); // 后续自行处理priceList即可 }
结果说明
两种方式最终都会提取到3条price明细,对应ID为111、222、333的三个商品的金额数据。
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

