Java中动态JSON映射POJO类及JsonNode解析疑难
Hey, let's work through your dynamic JSON parsing issue with Jackson—since your keys are all dynamic, rigid POJOs aren't the right fit, but we've got flexible alternatives that work perfectly.
1. Parsing Your Current root JsonNode Setup
You've already wrapped your data in a fixed root array, so extracting the dynamic keys and their values is straightforward. Just iterate over the array elements (each is a single-key object) and pull out the key and its corresponding array:
String jsonString = tdObj.getTempData(); TempDataTblPojo obj = new ObjectMapper().readValue(jsonString, TempDataTblPojo.class); JsonNode rootArray = obj.getRoot(); ObjectMapper mapper = new ObjectMapper(); // Reuse this instance for efficiency! for (JsonNode node : rootArray) { // Grab the only key in the object (since each element has one key) String dynamicKey = node.fieldNames().next(); // Get the array value associated with the key JsonNode valueArray = node.get(dynamicKey); // Convert to a Java List for easier use List<String> values = mapper.convertValue(valueArray, new TypeReference<List<String>>() {}); System.out.printf("Key: %s | Values: %s%n", dynamicKey, String.join(", ", values)); }
This will output:
Key: citycode | Values: 100, 1130385 Key: cityname | Values: London, 1130383 Key: statecode | Values: 512, 1130382
Pro tip: Reuse your ObjectMapper instance instead of creating new ones—it's more efficient!
2. A Better Approach: Skip the POJO & Handle Original JSON Directly
You don't need to convert your original Type 1 JSON to Type 2 (losing the outer dynamic key like city_master). Jackson can handle the original dynamic structure directly, preserving all your data:
Option A: Use JsonNode for Maximum Flexibility
// Your original Type 1 JSON String originalJson = "{\n \"city_master\": [\n { \"citycode\": [ \"100\", \"1130385\" ] },\n { \"cityname\": [ \"London\", \"1130383\" ] },\n { \"statecode\": [ \"512\", \"1130382\" ] }\n ]\n}"; ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(originalJson); // Get the outer dynamic key (e.g., "city_master") String outerDynamicKey = root.fieldNames().next(); JsonNode dataArray = root.get(outerDynamicKey); // Iterate through the inner data just like before for (JsonNode node : dataArray) { String innerDynamicKey = node.fieldNames().next(); List<String> values = mapper.convertValue(node.get(innerDynamicKey), new TypeReference<List<String>>() {}); System.out.printf("Outer Key: %s | Inner Key: %s | Values: %s%n", outerDynamicKey, innerDynamicKey, String.join(", ", values)); }
Option B: Use Generic Maps for Stronger Typing
If you prefer working with typed collections instead of JsonNode, use a TypeReference to parse directly into a nested map structure:
ObjectMapper mapper = new ObjectMapper(); TypeReference<Map<String, List<Map<String, List<String>>>>> typeRef = new TypeReference<>() {}; // Parse original Type 1 JSON directly into the map Map<String, List<Map<String, List<String>>>> dataMap = mapper.readValue(originalJson, typeRef); // Traverse the nested structure for (Map.Entry<String, List<Map<String, List<String>>>> outerEntry : dataMap.entrySet()) { String outerKey = outerEntry.getKey(); List<Map<String, List<String>>> innerList = outerEntry.getValue(); for (Map<String, List<String>> innerMap : innerList) { // Each inner map has exactly one key-value pair Map.Entry<String, List<String>> innerEntry = innerMap.entrySet().iterator().next(); String innerKey = innerEntry.getKey(); List<String> values = innerEntry.getValue(); System.out.printf("Outer Key: %s | Inner Key: %s | Values: %s%n", outerKey, innerKey, String.join(", ", values)); } }
3. Why This Works
Your JSON structure follows a consistent pattern even with dynamic keys:
Outer dynamic key → Array of single-key objects → Each key maps to an array of strings
Both JsonNode and generic maps let you work with this pattern without needing to define rigid POJOs. The original JSON approach also preserves the outer key (like city_master) which you mentioned you had to store separately before—this saves you extra work!
内容的提问来源于stack exchange,提问作者John

