Search code examples
javajsonjson-simple

Java 8 JSON-simple - How can i read a subitem?


I have a Problem in Java, specially in work with the JSON-simple Library. I have found here a code, they does work in the level of a parent node from a json-file but at my case, i read a json-file with childs under the parents.

Link to the code: How to read json file into java with simple JSON library

In DB-Language: i have a database with some tables. Now, i can only read "select * from table" but i want to read the column (or attribute) from it.


The Structure (raw data json):

{
"PARENT1":
{
"child_attr1":"0.00","child_attr2":"0.30"
},
"PARENT2":
{
"child_attr1":"0.10","child_attr2":"0.12"
},
"PARENT3":
{
"child_attr1":"0.03","child_attr2":"0.45"
}
}

The Code:

public static HttpResponse http(String url, String body) {    
    try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
        HttpPost request = new HttpPost(url);
        StringEntity params = new StringEntity(body);
        request.addHeader("content-type", "application/json");
        request.setEntity(params);
        HttpResponse result = httpClient.execute(request);

        String json_content = EntityUtils.toString(result.getEntity(), "UTF-8");
        //System.out.println(json_content);

        try {
            JSONParser parser = new JSONParser();
            Object resultObject = parser.parse(json_content);

            if (resultObject instanceof JSONArray) {
                JSONArray array=(JSONArray)resultObject;
                for (Object object : array) {
                    JSONObject obj =(JSONObject)object;
                    System.out.println(obj.get("Parent"));
                    System.out.println(obj.get("Child"));
                    //System.out.println("case1"); 
                }

            } else if (resultObject instanceof JSONObject) {
                JSONObject obj =(JSONObject)resultObject;
                System.out.println(obj.get("PARENT2"));
                //System.out.println("case2"); 
                //THIS KNOT WORKS BUT IT GIVES ME ALL VALUES OF THE ATTRIBUTES 


            }
        } catch (Exception e) {
          // TODO: handle exception
          e.printStackTrace();
        }
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    return null;
}

Solution

  • You have 1 "root" JSONObject, containing 3 nodes, each an instance of JSONObject. These 3 nodes each contains 2 nested nodes. json-simple will treat these as strings, if you traverse through the structure.

    To print out the contents of your parents, you'd have to do something similar to:

    JSONParser parser = new JSONParser();
    
    JSONObject parents = (JSONObject) parser.parse(new FileReader("filename"));
    
    JSONObject parent1 = (JSONObject) parents.get("PARENT1");
    JSONObject parent2 = (JSONObject) parents.get("PARENT2");
    JSONObject parent3 = (JSONObject) parents.get("PARENT3");
    
    System.out.println("Parent 1");
    System.out.println("\tChild 1: " + parent1.get("child_attr1"));
    System.out.println("\tChild 2: " + parent1.get("child_attr2"));
    
    System.out.println("Parent 2");
    System.out.println("\tChild 1: " + parent2.get("child_attr1"));
    System.out.println("\tChild 2: " + parent2.get("child_attr2"));
    
    System.out.println("Parent 3");
    System.out.println("\tChild 1: " + parent3.get("child_attr1"));
    System.out.println("\tChild 2: " + parent3.get("child_attr2"));
    

    This would ouput

    Parent 1
        Child 1: 0.00
        Child 2: 0.30
    Parent 2
        Child 1: 0.10
        Child 2: 0.12
    Parent 3
        Child 1: 0.03
        Child 2: 0.45
    

    If you want to be able to iterate over all the childs, you should define each parent as a JSONArray, and each child as a JSONObject

    {
        "PARENT1": [
            {"child_attr1": "0.00"},
            {"child_attr2": "0.30"}
        ],
        "PARENT2": [
            {"child_attr1": "0.10"},
            {"child_attr2": "0.12"}
        ],
        "PARENT3": [
            {"child_attr1": "0.14"},
            {"child_attr2": "0.45"}
        ]
    }
    

    If your structure would always follow this sample: 1 root object with x-amount parent array objects, each with y-amount child objects, where the child objects never have any nested nodes, one way to iterate over all of them would be:

    Iterator<?> i = parents.keySet().iterator();
    // Alternative, if you don't need the name of the key of the parent node:
    // Iterator<?> i = parents.values().iterator();
    while(i.hasNext()) {
        String parentKey = (String) i.next();
        JSONArray p = (JSONArray) parents.get(parentKey);
        System.out.println(parentKey);
    
        // If you don't need the name of the parent key node, 
        // replace the above with:
        // JSONArray p = (JSONArray) i.next();
        // Remember to use the alternative iterator-definition above as well
    
        for(Object o : p) {
            JSONObject child = (JSONObject) o;
            System.out.println("\t" + child.keySet() + ": " + child.values());
        }
    }
    

    The above (with the parent node names) would output:

    PARENT1
        [child_attr1]: [0.00]
        [child_attr2]: [0.30]
    PARENT3
        [child_attr1]: [0.14]
        [child_attr2]: [0.25]
    PARENT2
        [child_attr1]: [0.10]
        [child_attr2]: [0.12]
    

    When calling #keySet() and #values() on the child node, it will return as a Set and a Collection, respectively. When using #toString() on these, the output will be printed enclosed in brackets ([keys/values]). You can of course just ask for an array, and then the first entry, to get the lonely key/value: child.keySet().toArray()[0] and child.values().toArray()[0]. This won't of course work, if you have nested nodes inside your child nodes - in such case, it would only print the first key/value for the particular node.