How to parse a nested JSON array having a combination of strings and integers to a POJO in Java?

Viewed 316

The Java application I am working on calls an external API that gives the following response in JSON format.

 {
    "response": {
        "version": "1.2.0",
        "data": [
            [
                "*",
                [
                    "core1",
                    1
                ],
                [
                    "core2",
                    1
                ],
                [
                    "core3",
                    1
                ]

            ],
            [
                "*",
                [
                    "{\"frame\":[\"frame1\",\"frame2\"]}",
                    10
                ]
            ],
            [
                "*",
                [
                    null,
                    10
                ]
            ]
        ]
    }
}

I am trying to map the response to a POJO using the following;

private String version; 
private  List<List<Object>> values;

Although the values of data are mapped as , I am unable to iterate and extract each content from it. My requirement is to get core1, core2, core3 to a variable coreLists and frame to frameList from the values of data. Is there a better way to map data field to POJO correctly and iterate and extract the values and assign each to separate lists?

1 Answers

I personally don't want to parse it directly to List<List<Object>> because in the end, I have to use parser to parse "{\"frame\":[\"frame1\",\"frame2\"]}" from string Json/HashMap anyway.

Step 1: parse json string to your POJO

I use Gson as a parser

        String json = "{\"response\":{\"version\":\"1.2.0\",\"data\":[[\"*\",[\"core1\",1],[\"core2\",1],[\"core3\",1]],[\"*\",[\"{\\\"frame\\\":[\\\"frame1\\\",\\\"frame2\\\"]}\",10]],[\"*\",[null,10]]]}}";
        Map<String, Map<String, Object>> map = new Gson().fromJson(json, new TypeToken<>(){}.getType());
        Map<String, Object> response = map.get("response");
        String version = (String) response.get("version");

        List<List<Object>> values = (List<List<Object>>) response.get("data");

        MyPOJO pojo = new MyPOJO(version, values);

Okay, let's inspect pojo (god bless VSCode):

enter image description here

As you can see, elements in arrays of values arrays could be either String * or array-ception so we have to check the type of it.

Step 2: extract coreLists

Because you don't mention how core will appear so I'll assume that it only appears in the first element of the values array. You can add more checks for safer. ie: string or double

        List<String> coreLists = new ArrayList<>();

        for (Object coreCandidate : pojo.getValues().get(0)) {
            if (coreCandidate instanceof ArrayList) {
                List<Object> temp = (List<Object>)coreCandidate;
                coreLists.add((String) temp.get(0));
            }
        }

Step 3: extract frameList

Do the same as extract coreLists but add Gson parser one more time

        List<String> frameList = new ArrayList<>();

        for (Object coreCandidate : pojo.getValues().get(1)) {
            if (coreCandidate instanceof ArrayList) {
                List<Object> temp = (List<Object>) coreCandidate;
                Map<String, List<String>> frames = new Gson().fromJson((String) temp.get(0), new TypeToken<>() {}.getType());
                frameList.addAll(frames.get("frame"));
            }
        }

If this is good enough, feels free to vote up

Related