简体   繁体   中英

Get list of keys in Complex JSON Object (Java 8)

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?

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]

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 准备好了!

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();
…

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM