0

I am dealing with a JSON that looks like this :-

{
"key1": {
    "key1.1": {
        "nestedkey1": "something",
        "nestedkey2": "something",
        "nestedkey3": "Something"
    },
    "key1.2": {
        "nestedkey1": "something",
        "nestedkey2": "something",
        "nestedkey3": "Something"
    }
},
"key2": {
    "key2.1": {
        "nestedkey1": "something",
        "nestedkey2": "something",
        "nestedkey3": "Something"
    },
    "key2.2": {
        "nestedkey1": "something",
        "nestedkey2": "something",
        "nestedkey3": "Something"
    }
}...

And I don't know all the keys. I wish to obtain all the keys so that I can create a Map<String, Object> out of this. That map should look something like ("key1" -> Corresponding object)...

Is there a simple way to do this in Java?

2
  • Do you need to unwrap all nested maps and have compound keys like: "key1-key1.1-nestedkey1": "something"? Commented Sep 22, 2020 at 14:10
  • @AlexRudenko no nothing like that. although if that is possible it'd be EXTREMELY helpful. Commented Sep 22, 2020 at 14:17

3 Answers 3

2

String filePath ="src/main/resources/json/1.json";
FileReader reader = new FileReader(filePath);

JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(reader);

Set<String> setKeys= jsonObject.keySet();
Map<String,Object> yourMap= new HashMap<>();
for (String key:setKeys) {
yourMap.put(key,jsonObject.get(key));
}

yourMap is ready!

Sign up to request clarification or add additional context in comments.

Comments

1

Using Jackson JSON library, this json may be parsed as a Map<String, Object> using TypeReference:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

public class JsonTest {

    public static void main(String[] args) throws JsonProcessingException {
        String json = "{\n"
                + "\"key1\": {\n"
                + "    \"key1.1\": {\n"
                + "        \"nestedkey1\": \"something\",\n"
                + "        \"nestedkey2\": \"something\",\n"
                + "        \"nestedkey3\": \"Something\"\n"
                + "    },\n"
                + "    \"key1.2\": {\n"
                + "        \"nestedkey1\": \"something\",\n"
                + "        \"nestedkey2\": \"something\",\n"
                + "        \"nestedkey3\": \"Something\"\n"
                + "    }\n"
                + "},\n"
                + "\"key2\": {\n"
                + "    \"key2.1\": {\n"
                + "        \"nestedkey1\": \"something\",\n"
                + "        \"nestedkey2\": \"something\",\n"
                + "        \"nestedkey3\": \"Something\"\n"
                + "    },\n"
                + "    \"key2.2\": {\n"
                + "        \"nestedkey1\": \"something\",\n"
                + "        \"nestedkey2\": \"something\",\n"
                + "        \"nestedkey3\": \"Something\"\n"
                + "    }\n"
                + "}}"; // make sure the json is valid and closing } is available

        ObjectMapper mapper = new ObjectMapper();

        Map<String, Object> map = mapper.readValue(json, new TypeReference<>() {});

        System.out.println(map);
    }
}

To get the list of all keys, a recursive method needs to be implemented to iterate over the entries of the top-level map and add keys:

public static List<String> getKeys(Map<String, Object> map) {
    List<String> keys = new ArrayList<>();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        keys.add(entry.getKey());
        if (entry.getValue() instanceof Map) {
            Map<String, Object> nested = (Map<String, Object>) entry.getValue();
            keys.addAll(getKeys(nested));
        }
    }
    return keys;
}

Similarly, a list of "prefixed" keys may be created:

public static List<String> getPrefixedKeys(String prefix, Map<String, Object> map) {
    List<String> keys = new ArrayList<>();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        String key = prefix + entry.getKey();
        keys.add(key);
        if (entry.getValue() instanceof Map) {
            Map<String, Object> nested = (Map<String, Object>) entry.getValue();
            keys.addAll(getPrefixedKeys(key + "/", nested));
        }
    }
    return keys;
}

// test
System.out.println(getPrefixedKeys("/", map));

Output:

[/key1, /key1/key1.1, /key1/key1.1/nestedkey1, /key1/key1.1/nestedkey2, /key1/key1.1/nestedkey3, 
/key1/key1.2, /key1/key1.2/nestedkey1, /key1/key1.2/nestedkey2, /key1/key1.2/nestedkey3, 
/key2, /key2/key2.1, /key2/key2.1/nestedkey1, /key2/key2.1/nestedkey2, /key2/key2.1/nestedkey3, 
/key2/key2.2, /key2/key2.2/nestedkey1, /key2/key2.2/nestedkey2, /key2/key2.2/nestedkey3]

Comments

0

The computing task is to output field names of all levels in JSON records of indefinite number of levels. The code will be lengthy if you try to handle such a scenario in Java.

It is convenient to do this in SPL, the open-source Java package. Three lines of code are enough:

A B
1 =i=0,json(file("records.json").read())
2 func recurse(r) >i+=1,r.fno().run(tmp=eval("r.#"/~),B1=B1.to(:i-1)|r.fname(~),output(B1.concat("->")),if(ifr(tmp),func(recurse,tmp),(B1=B1|tmp)))
3 =func(recurse,A1)

SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as jsonkeys.splx and invoke it in Java as you call a stored procedure:

…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call jsonkeys()");
st.execute();
…

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.