Write java class with nested Map to custom json format using Gson

Tags: , ,



What Java data structure can be used to serialize to the following Json which have a set of child objects?

Example:

{
    "John": {
        "Type": "Person",
        "age": 30,
        "Sean": {
            "Type": "child",
            "age": 3
        },
        "Julian": {
            "Type": "child",
            "age": 4
        }
    },
    "Paul": {
        "Type": "Person",
        "age": 64,
        "Stella": {
            "Type": "child",
            "age": 10
        },
        "James": {
            "Type": "child",
            "age": 12
        }
    }
}

Writing John and Paul can be done by: Map<String,Person> but i cannot figure out how to nest the Child without having the ‘children’ property.

Example:

{
    "John": {
        "Type": "Person",
        "age": 30,
        "children": {
            "Sean": {
                "Type": "child",
                "age": 3
            },
            "Julian": {
                "Type": "child",
                "age": 4
            }
        }
    }
}

I am not sure it is relevant, but Gson is being used to create the Json file

Answer

I’m not sure wheher this is possible with GSON though it’s possible with Jackson.

With GSON you can try custom JsonSerializer, which might look something like this:

private static class PersonTypeSerializer implements JsonSerializer<Person> {

    @Override
    public JsonElement serialize(Person person, Type type, JsonSerializationContext jsonSerializationContext) {
        JsonObject personJson = personToJson(person);
        for (Map.Entry<String, Person> child : person.getChildren().entrySet()) {
            personJson.add(child.getKey(), personToJson(child.getValue()));
        }
        return personJson;
    }

    private static JsonObject personToJson(Person person) {
        JsonObject personJson = new JsonObject();
        personJson.addProperty("Type", person.getType());
        personJson.addProperty("age", person.getAge());

        return personJson;
    }
}

and register to GSON instance like this:

Gson gson = new GsonBuilder().registerTypeAdapter(Person.class, new PersonTypeSerializer())
                             .create();

Note that code assumes that both type "Person" and "child" are represented by the same Person class. It should be pretty easy to modify this if not.



Source: stackoverflow