0

I have an expected json file as below. It is a nested object

{
    "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
                    }
                ]
            }]
        }
    }]
}

How to add all field name and value of all items inside this object into List? I tried using the following way but it is not as expected.

//Get all key name in json object

```public static List<String> getAllKeysInJsonUsingJsonNodeFieldNames(String json) {
    ObjectMapper mapper = new ObjectMapper()
    List<String> keys = new ArrayList<>();
    JsonNode jsonNode = mapper.readTree(json);
    getAllKeysUsingJsonNodeFields(jsonNode, keys);
    return keys;
}

public static void getAllKeysUsingJsonNodeFields(JsonNode jsonNode, List<String> keys) {
    if (jsonNode.isObject()) {
        Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
        fields.forEachRemaining({def field ->
            keys.add(field.getKey());
            getAllKeysUsingJsonNodeFields((JsonNode) field.getValue(), keys);
        });
    } else if (jsonNode.isArray()) {
        ArrayNode arrayField = (ArrayNode) jsonNode;
        arrayField.forEach({def node ->
            getAllKeysUsingJsonNodeFields(node, keys);
        });
    }
}```

The result as below => It only shows only field name without figure out that field belong to which object

TagName[i] = s_code

I expect that the result should be below, specifically, I want to field name should be shown it belongs to which object => Could you tell me how to resolve it?

TagName[i] = contact_status.term_list[0].t_list[0].s_code

Sorry for I'm a new in Java => If anyone know a way to resolve it please tell me in more details. Thank you so much!

TaraNG
  • 17
  • 4

3 Answers3

0

Below code for add field names and values of a JSON object into List<String> using jsonNode:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonToListExample {
    public static void main(String[] args) throws Exception {
        String jsonStr = "{\"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}]}]}}]}";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode rootNode = mapper.readTree(jsonStr);
        List<String> fieldList = new ArrayList<>();
        checkFields(rootNode, fieldList);
        System.out.println(fieldList);

    }

    private static void checkFields(JsonNode node, List<String> fieldList) {
        Iterator<String> fieldNames = node.fieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();
            JsonNode fieldValue = node.get(fieldName);
            if (fieldValue.isObject()) {
                checkFields(fieldValue, fieldList);
            } else if (fieldValue.isArray()) {
                for (JsonNode arrayNode : fieldValue) {
                    checkFields(arrayNode, fieldList);
                }
            } else {
                String fieldStr = fieldName + ": " + fieldValue.toString();
                fieldList.add(fieldStr);
            }
        }
    }
}
Jai Prakash
  • 162
  • 1
  • 10
  • May I ask you additional question? I expect that the result should be below, specifically, I want to field name should be shown it belongs to which object => whether it is able to resolve with your solution? contact_id = Contact_001; contact_status.exam_status = 0; contact_status.term_list[0].term_code = 110; – TaraNG Mar 09 '23 at 05:21
0

This code does what you want.

private static String jsonParserTest() {
    try {
        Map createdMap = new HashMap<String, Object>();
        Map<String, Object> tempMap  = new HashMap<>();
        List<Map> tempList = new ArrayList<>();
        tempMap.put("s_code", 12001);
        tempMap.put("sexam_status", 0);
        tempList.add(tempMap);
        tempMap = new HashMap<>();
        tempMap.put("s_code", 13001);
        tempMap.put("sexam_status", 1);
        tempList.add(tempMap);
        tempMap  = new HashMap<>();
        tempMap.put("term_code", 110);
        tempMap.put("t_list", tempList);
        tempList = new ArrayList<>();
        tempList.add(tempMap);
        tempList = new ArrayList<>();
        tempList.add(tempMap);
        tempMap  = new HashMap<>();
        tempMap.put("exam_status", 0);
        tempMap.put("term_list", tempList);
        Map<String, Object> tempMap2  = new HashMap<>();
        tempMap2.put("contact_status", tempMap);
        tempMap2.put("contact_id", "Contact_001");
        tempList = new ArrayList<>();
        tempList.add(tempMap2);
        createdMap.put("contact_info", tempList);
        String jsonString = JsonUtils.writeObjectToJsonString(createdMap);
        System.out.println(jsonString);
        return jsonString;
    } catch (IOException e) {
        System.out.println(TextUtils.getStacktrace(e));
    }
}

The return String is:

{
   "contact_info": {
      "contact_status": {
         "exam_status": 0,
         "term_list": [
            {
               "t_list": [
                  {
                     "s_code": 12001,
                     "sexam_status": 0
                  },
                  {
                     "s_code": 13001,
                     "sexam_status": 1
                  }
               ],
               "term_code": 110
            }
         ]
      },
      "contact_id": "Contact_001"
   }
}

And this String is the same Json as yours. Basically you need to build your map the way you want your JSON to look and than just serialize it to Json. In This code I used classes JsonUtils and TextUtils. JsonUtils class is a thin wrapper over Jason-Jackson library and it makes serializing and parsing simpler. Thise classes come from Open Source MgntUtils library written and maintained by me. You can get this library as Maven artifact here or here and also on Github with source code and Javadoc. Here is JsoonUtils Javadoc

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
0

You can use JSON library such as Josson to do the transformation.

https://github.com/octomix/josson

Deserialization

Josson josson = Josson.fromJsonString(
    "{" +
    "    \"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" +
    "                    }" +
    "                ]" +
    "            }]" +
    "        }" +
    "    }]" +
    "}");

Query the keys and values in separate arrays

Josson flattened = josson.getJosson("contact_info[0].flatten('.','[%d]')");

System.out.println("-- Keys --");
JsonNode node = flattened.getNode("keys()");
List<String> keys = new ArrayList<>();
node.elements().forEachRemaining(elem -> keys.add(elem.asText()));
keys.forEach(System.out::println);

System.out.println("-- Values --");
node = flattened.getNode("toArray()");
List<String> values = new ArrayList<>();
node.elements().forEachRemaining(elem -> values.add(elem.toString()));
values.forEach(System.out::println);

Output

-- Keys --
contact_id
contact_status.exam_status
contact_status.term_list[0].term_code
contact_status.term_list[0].t_list[0].s_code
contact_status.term_list[0].t_list[0].sexam_status
contact_status.term_list[0].t_list[1].s_code
contact_status.term_list[0].t_list[1].sexam_status
-- Values --
"Contact_001"
0
110
12001
0
13001
1

Query the keys and values in single array

JsonNode node = josson.getNode("contact_info[0].flatten('.','[%d]').entries().concat(key,' = ',value)");
List<String> keyValues = new ArrayList<>();
node.elements().forEachRemaining(elem -> keyValues.add(elem.asText()));
keyValues.forEach(System.out::println);

Output

contact_id = Contact_001
contact_status.exam_status = 0
contact_status.term_list[0].term_code = 110
contact_status.term_list[0].t_list[0].s_code = 12001
contact_status.term_list[0].t_list[0].sexam_status = 0
contact_status.term_list[0].t_list[1].s_code = 13001
contact_status.term_list[0].t_list[1].sexam_status = 1
Raymond Choi
  • 1,065
  • 2
  • 7
  • 8
  • Thanks for helping me! May I ask you additional question? I want to save Key and Value into 2 different string list => Could you tell me How I should write code using Josson you recommended? Keylist[5] = contact_status.term_list[0].t_list[1].s_code Valuelist[5] = 13001 – TaraNG Mar 02 '23 at 02:25
  • Thanks a lot for helping! Whether we can get datatype according to Expected Json? For example: Keylist[1] = contact_id ; Valuelist[1] = "Contact_001". Keylist[2] = contact_status.exam_status; Valuelist[2] = 0 using the same method you suggested? Currently I tried and it always save value without the character [""] for string value – TaraNG Mar 02 '23 at 07:53
  • May I ask you additional question? In case contact_info contains a lot objects, e.g contact_info[0], contact_info[1]... So How should the following code be updated to List can contain all according contact_info objects and keys? With the following code => It only proceeds for the first contact_info object Josson flattened = josson.getJosson("contact_info[0].flatten('.','[%d]')"); – TaraNG Mar 03 '23 at 09:54
  • 1
    Try `"flatten('.','[%d]')"` – Raymond Choi Mar 03 '23 at 10:02
  • May I ask you additional question? In case contact_info contains object or array that are empty like this {"contact_info": [{ "contact_id": "Contact_001", "contact_status": {}, "cont_HD":[]}]} => with the above method => It does not return the object contact_status and array cont_HD that are empty => Whether Is there is any way to get object or array that is empty? My return expected for above ex as below: For key: key[0]=contact_info[0].contact_id; key[1]=contact_info[0].contact_status; key[2]=contact_info[0].cont_HD; For value: value[0]="Contact_001"; value[1]=; value[2]=; – TaraNG Mar 08 '23 at 23:45
  • There is no solution for this case using _Josson_ currently. – Raymond Choi Mar 09 '23 at 01:04
  • So whether there is any way that not using Josson and resolve this case? I've created another question below => If you know any solution => Could you please tell me? Thank you! https://stackoverflow.com/questions/75679849/how-to-get-object-or-array-with-value-null-in-a-nested-json-object – TaraNG Mar 09 '23 at 04:04