Reputated_Enginius
Reputated_Enginius

Reputation: 336

How to create a Java method to parse a big JSON file

I am trying to parse the content of JSON file text.json by using Jackson library.

What I want is to make a java method to get all keys and values of it, but so far in my code I get only the first key and the first value of the JSON file.

The code snippet I used as guidance to make my own Java class is the following:

public void parse(String json)  {
    JsonFactory factory = new JsonFactory();

    ObjectMapper mapper = new ObjectMapper(factory);
    JsonNode rootNode = mapper.readTree(json);  

    Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.fields();
    while (fieldsIterator.hasNext()) {

        Map.Entry<String,JsonNode> field = fieldsIterator.next();
        System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
    }
}

And my Java class that I created is shown below:

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

public class JacksonStreamExample {
    public static void main(String[] args) {
        try {
            //Create a JsonFactory instance
            JsonFactory factory = new JsonFactory();

            //Create a JsonParser instance to read from file c:\\text.json
            JsonParser jParser = factory.createJsonParser(new File("c:\\text.json"));

            /*Create an ObjectMapper instance to provide a pointer
             * to root node of the tree after reading the JSON
             */
            ObjectMapper mapper = new ObjectMapper(factory);

            //Create tree from JSON
            JsonNode rootNode = mapper.readTree(jParser);  

            Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.getFields();
            while (fieldsIterator.hasNext()) {
                Map.Entry<String,JsonNode> field = fieldsIterator.next();
                System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
            }

            jParser.close();

        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

My Eclipse output is the following which creates only 1 pair(key-value):

Key: cells  Value:[{"type":"basic.Circle","size":{"width":90,"height":54},"position":{"x":-80,"y":200},"angle":0,"id":"cae4c219-c2cd-4a4b-b50c-0f269963ca24","embeds":"","z":1,"wi_name":"START","wi_displayName":"START","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"circle":{"fill":"#000000","width":50,"height":30,"stroke-width":1,"stroke-dasharray":"0"},"text":{"font-size":10,"text":"START","fill":"#ffffff","font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Circle","size":{"width":90,"height":54},"position":{"x":210,"y":200},"angle":0,"id":"d23133e0-e516-4f72-8127-292545d3d479","embeds":"","z":2,"wi_name":"END","wi_displayName":"END","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"circle":{"fill":"#000000","width":50,"height":30,"stroke-width":1,"stroke-dasharray":"0"},"text":{"font-size":10,"text":"END","fill":"#ffffff","font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Rect","position":{"x":-80,"y":370},"size":{"width":90,"height":54},"angle":0,"id":"a53898a5-c018-45c4-bd3f-4ea4d69f58ed","embeds":"","z":3,"wi_name":"ACTIVITY_1","wi_displayName":"ACTIVITY 1","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"rect":{"width":50,"height":30,"rx":2,"ry":2,"stroke-width":1,"stroke-dasharray":"0"},"text":{"text":"Activity","font-size":10,"font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"basic.Rect","position":{"x":220,"y":370},"size":{"width":90,"height":54},"angle":0,"id":"e2bd21f2-508d-44b9-9f68-e374d4fa87ea","embeds":"","z":4,"wi_name":"ACTIVITY_2","wi_displayName":"ACTIVITY 2","wi_description":"","wi_join":"<None>","wi_split":"<None>","wi_performingRole":"<None>","wi_expected_activity_time":null,"wi_expected_user_time":null,"wi_maximum_activity_time":null,"wi_initial_delay":null,"wi_time_unit":"Seconds","wi_required_transitions_for_AND_JOIN":null,"wi_custom_page":"","attrs":{"rect":{"width":50,"height":30,"rx":2,"ry":2,"stroke-width":1,"stroke-dasharray":"0"},"text":{"text":"Workitem","font-size":10,"font-family":"Arial","stroke":"#000000","stroke-width":0,"font-weight":400}}},{"type":"link","source":{"id":"cae4c219-c2cd-4a4b-b50c-0f269963ca24"},"target":{"id":"d23133e0-e516-4f72-8127-292545d3d479"},"router":{"name":"manhattan"},"labels":[{"position":0.5,"attrs":{"text":{"text":"Name"}}}],"id":"60ee7ff7-3a3b-487d-b581-49027e7bebe4","embeds":"","z":5,"attrs":{".marker-source":{"d":"M 10 0 L 0 5 L 10 10 z","transform":"scale(0.001)"},".marker-target":{"d":"M 10 0 L 0 5 L 10 10 z"},".connection":{"stroke":"black"}}},{"type":"link","source":{"id":"a53898a5-c018-45c4-bd3f-4ea4d69f58ed"},"target":{"id":"e2bd21f2-508d-44b9-9f68-e374d4fa87ea"},"router":{"name":"manhattan"},"labels":[{"position":0.5,"attrs":{"text":{"text":"Name"}}}],"id":"cea0d1c2-2c18-4bd7-ba35-d94918c6fc9b","embeds":"","z":6,"attrs":{".marker-source":{"d":"M 10 0 L 0 5 L 10 10 z","transform":"scale(0.001)"},".marker-target":{"d":"M 10 0 L 0 5 L 10 10 z"},".connection":{"stroke":"black"}}}]

I just need to make a method to put this code inside to get all key-value pairs:

//Create a JsonFactory instance
JsonFactory factory = new JsonFactory();

//Create a JsonParser instance to read from file c:\\text.json
JsonParser jParser = factory.createJsonParser(new File("c:\\text.json"));

/*Create an ObjectMapper instance to provide a pointer
 *to root node of the tree after reading the JSON
 */
ObjectMapper mapper = new ObjectMapper(factory);

//Create tree from JSON
JsonNode rootNode = mapper.readTree(jParser);  


Iterator<Map.Entry<String,JsonNode>> fieldsIterator = rootNode.getFields();
while (fieldsIterator.hasNext()) {

    Map.Entry<String,JsonNode> field = fieldsIterator.next();
    System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}

How will I do it please?

Upvotes: 1

Views: 2138

Answers (3)

Reputated_Enginius
Reputated_Enginius

Reputation: 336

I solved my problem by changing JSON library.

I used json-simple-1.1.1

My final code that worked is the following:

package jsontoxml;

import java.io.*;

import org.json.simple.parser.JSONParser;
import org.json.simple.*;
import java.util.*;


public class JacksonStreamExample {

   public static void main(String[] args) {
       JSONParser parser = new JSONParser();
     try {
        Object obj = parser.parse(new FileReader("text.json"));
        JSONObject jsonObject = (JSONObject) obj;

        JSONArray cells = (JSONArray) jsonObject.get("cells");
        Iterator<JSONObject> iterator = cells.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

     } catch (Exception e) {

      e.printStackTrace();

     }

  }

}

Upvotes: 2

Pavan Kumar
Pavan Kumar

Reputation: 4820

Now that you have modified the question and json, here is the solution you're looking for:

public static void main(String[] args) {
    try {
        Map source = (new ObjectMapper()).readValue(new File(
                "C:\\json.txt"), Map.class);

        Map<String, Object> result = new LinkedHashMap<>();
        buildFlattenedMap(result, source, null);
        for (String s : result.keySet()) {
             System.out.println(s);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static void buildFlattenedMap(Map<String, Object> result,
        Map<String, Object> source, String path) {
    for (Map.Entry<String, Object> entry : source.entrySet()) {
        String key = entry.getKey();
        if (hasText(path)) {
            if (key.charAt(0) == '[') {
                key = StringUtils.join(path, key);
            } else {
                key = StringUtils.join(path, '.', key);
            }
        }
        Object value = entry.getValue();
        if (value instanceof String) {
            result.put(key, value);
        } else if (value instanceof Map) {
            // Need a compound key
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) value;
            buildFlattenedMap(result, map, key);
        } else if (value instanceof Collection) {
            // Need a compound key
            @SuppressWarnings("unchecked")
            Collection<Object> collection = (Collection<Object>) value;
            int count = 0;
            for (Object object : collection) {
                buildFlattenedMap(result, Collections.singletonMap("["
                        + (count++) + "]", object), key);
            }
        } else {
            result.put(key, value == null ? StringUtils.EMPTY : value);
        }
    }
}

private static boolean hasText(CharSequence str) {
    if (StringUtils.isEmpty(str)) {
        return false;
    }
    int strLen = str.length();
    for (int i = 0; i < strLen; i++) {
        if (!Character.isWhitespace(str.charAt(i))) {
            return true;
        }
    }
    return false;
}

FYI, buildFlattenedMap method is actually from spring framework which I had used recently for processing a similar stuff. https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/factory/config/YamlProcessor.java

Upvotes: 1

Robby Cornelissen
Robby Cornelissen

Reputation: 97150

You should use Jackson2 instead of Jackson1. As the error message specifies, Jackson1's JsonNode indeed does not have this fields() method, while Jackson2's version does.

In Jackson1, you would have to do something like this:

Iterator<String> fieldNameIterator = rootNode.getFieldNames();

while (fieldNameIterator.hasNext()) {
    String fieldName = fieldNameIterator.next();
    JsonNode fieldValue = rootNode.getFieldValue(fieldName);

    System.out.println("Key: " + fieldName + "\tValue:" + fieldValue);
}

Upvotes: 2

Related Questions