简体   繁体   中英

Convert nested JsonArray in Map Java

I am trying to write a generic code were a JSON array as below example can be converted to a map .

This is sample . where parent element is menu

{"menu": {    
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},        
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},            
        {"id": "Quality"},
        {"id": "Pause"}
    ]
}}

to map having map values as :

menu.items_0.id=open    
menu.items_1.id=OpenNew
menu.items_1.label=Open New    
menu.items_2.id=ZoomIn
menu.items_2.label=Zoom In    
menu.items_3.id=ZoomOut
menu.items_3.id=Zoom Out    
menu.items_4.id=Quality    
menu.items_5.id=Pause

For my answer you need these classes:

org.json.JSONArray;
org.json.JSONException;
org.json.JSONObject;

And I'm assuming a class like this:

public class menu{
    private String id;
    private String label;
}

To parse - I'm ignoring if it's a stream, file, etc -. However, it assumes you've manipulated your source to create a single long String object called myString.

JSONObject topLevel = new JSONObject( myString );
JSONObject itemsArray= topLevel.getJSONArray("items");

int tempID;
String tempLabel;

//Now go through all items in array.
for(int i =0; i < itemsArray.length(); i++){
    tempID = itemsArray.getJSONObject(i).getString("id");

    if(itemsArray.getJSONObject(i).has("label"))
        tempLabel = itemsArray.getJSONObject(i).getString("label");
    else
        tempLabel = null;

    //whatever action you need to take
    menu = new menu( tempId, tempLabel);
}

This code here gets the job done. You can extract some methods, or refactor it a little, but it should do the trick.

public class Example {

    public static void main(String[] args) {

        String source = "{\"menu\": {\"items\": [{\"id\": \"Open\"},{\"id\": \"OpenNew\", \"label\": \"Open New\"}, " +
                "{\"id\": \"ZoomIn\", \"label\": \"Zoom In\"},"
                + "{\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"},{\"id\": \"Quality\"},{\"id\": \"Pause\"}"
                + "]}}";

        JSONObject jsonObject = new JSONObject(source);

        Map<String, Object> map = jsonObject.toMap();

        Map<String, String> resultMap = new HashMap<>();

        map
                .entrySet()
                .forEach(entry -> addToResult(entry, resultMap, "", ""));

        System.out.println(resultMap);

    }

    private static void addToResult(Map.Entry<String, Object> entry, Map<String, String> resultMap, String fieldNameAcummulator, String index) {
        Object value = entry.getValue();
        if (!Map.class.isAssignableFrom(value.getClass()) && !List.class.isAssignableFrom(value.getClass())) {
            resultMap.put(addToAccumulator(entry, fieldNameAcummulator, index), (String) value);
            return;
        }

        if (Map.class.isAssignableFrom(value.getClass())) {
            Map<String, Object> nestedMap = (HashMap<String, Object>) value;
            nestedMap
                    .entrySet()
                    .forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), ""));
        } else {
            List<HashMap<String, Object>> hashMaps = (List<HashMap<String, Object>>) value;
            IntStream.range(0, hashMaps.size())
                    .forEach(listIndex -> {
                        HashMap<String, Object> nestedMap = hashMaps.get(listIndex);
                        nestedMap.entrySet().forEach(nestedEntry -> addToResult(nestedEntry, resultMap, addToAccumulator(entry, fieldNameAcummulator, index), String.valueOf(listIndex)));
                    });
        }
    }

    private static String addToAccumulator(Map.Entry<String, Object> entry, String fieldNameAcummulator, String index) {
        return fieldNameAcummulator.isEmpty()
                ? entry.getKey()
                : fieldNameAcummulator + getKeyValueWithIndex(entry, index);
    }

    private static String getKeyValueWithIndex(Map.Entry<String, Object> entry, String index) {
        return index.isEmpty()
                ? ".".concat(entry.getKey())
                : "_".concat(index).concat(".").concat(entry.getKey());
    }
}

Feel free to ask if you have any questions regarding the implementation.

Hope it helps!

I have change some logic and it works fine after that.

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;

public class JsonToMapConvertor {

    private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
    public static JsonParser parser = new JsonParser();

    public static void main(String[] args) throws Exception{

    String json ="{\n" +
"    \"glossary\": {\n" +
"        \"title\": \"example glossary\",\n" +
"       \"GlossDiv\": {\n" +
"            \"title\": \"S\",\n" +
"           \"GlossList\": {\n" +
"                \"GlossEntry\": {\n" +
"                    \"ID\": \"SGML\",\n" +
"                   \"SortAs\": \"SGML\",\n" +
"                   \"GlossTerm\": \"Standard Generalized Markup Language\",\n" +
"                   \"Acronym\": \"SGML\",\n" +
"                   \"Abbrev\": \"ISO 8879:1986\",\n" +
"                   \"GlossDef\": {\n" +
"                        \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n" +
"                       \"GlossSeeAlso\": [\"GML\", \"XML\"]\n" +
"                    },\n" +
"                   \"GlossSee\": \"markup\"\n" +
"                }\n" +
"            }\n" +
"        }\n" +
"    }\n" +
"}";

       HashMap<String, Object> map = createHashMapFromJsonString(json,""); 
        System.out.println("map size "+map.size());

        for (Map.Entry<String, Object> entry : map.entrySet()) {            
          if(!entry.getValue().toString().contains("{"))  
                System.out.println(entry.getKey()+" : "+entry.getValue());
        }

    }

public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) throws Exception{   

    if(json.startsWith("[",0)){        
        JSONArray jsonArray = new JSONArray(json);    
            for (int i = 0; i < jsonArray.length(); i++){
                JSONObject jsonobject = jsonArray.getJSONObject(i);               
                createHashMapFromJsonString(jsonobject.toString(), prefix+"_"+i);
            }        
    }    
    else{

        JsonObject object = (JsonObject) parser.parse(json);   
        Set<Map.Entry<String, JsonElement>> set = object.entrySet();
        Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
        while (iterator.hasNext()) {

            Map.Entry<String, JsonElement> entry = iterator.next(); 
            String key = entry.getKey();

            if(prefix.length()!=0){
                key = prefix + "."+key;
            }

            JsonElement value = entry.getValue();
            if (null != value) {            
                if (!value.isJsonPrimitive()) {
                    if (value.isJsonObject()) {                        
                        mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
                    } else if (value.isJsonArray() && value.toString().contains(":")) {

                        List<HashMap<String, Object>> list = new ArrayList<>();
                        JsonArray array = value.getAsJsonArray();
                        if (null != array) {
                            for (JsonElement element : array) {                               
                                if (!element.isJsonPrimitive()) {
                                       createHashMapFromJsonString(value.toString(),key);
                                }else{
                                    list.add(createHashMapFromJsonString(value.toString(),key));
                                    }
                                }                 
                            mapReturn.put(key, list);
                        }
                    } else if (value.isJsonArray() && !value.toString().contains(":")) {                    
                        mapReturn.put(key, value.getAsJsonArray());
                    }              
                } else {
                    mapReturn.put(key, value.getAsString());
                }
            }
        }
    }
    return mapReturn;
  }
}

Just another way of converting JSONObject as List of Map as Generic

public static List<Map<String, Object>> getJsonNode(String jsonContents, String nodeName)
        throws JsonProcessingException, IOException, ParseException {
    JSONParser parser = new JSONParser();
    JSONObject json = (JSONObject) parser.parse(jsonContents);

    Object o = json.get(nodeName);
    List<Map<String, Object>> results = Lists.newArrayList();

    if (o instanceof JSONObject) {
        results.add((Map<String, Object>) o);
    } else if (o instanceof JSONArray) {
        List<Map<String, Object>> hashMaps = (List<Map<String, Object>>) o;
        results.addAll((Collection<? extends Map<String, Object>>) hashMaps);
    }
    return results;
}

/**
 * Driver
 * 
 * @param args
 * @throws IOException
 * @throws ParseException
 */
public static void main(String[] args) throws IOException, ParseException {
    String jsonInputFile = "temp/input.json";
    String jsonContents = new String(Files.readAllBytes(Paths.get(jsonInputFile)));

    List<Map<String, Object>> results = getJsonNode(jsonContents, "summary");
    for (Map<String, Object> entry : results) {
        System.out.println(entry);
    }
    ///////////////////////////////////////
    results = getJsonNode(jsonContents, "payWay");
    for (Map<String, Object> entry : results) {
        System.out.println(entry);
    }
    ///////////////////////////////////////
    results = getJsonNode(jsonContents, "sellerDetails");
    for (Map<String, Object> entry : results) {
        System.out.println(entry);
    }
}

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