Psychokiller1888
Psychokiller1888

Reputation: 650

Parsing to class with GSON

I'm trying to parse a particular JSON file using GSON. Up to now, it worked well, because all the JSON I treated had properties for the data.

But I stumble onto this data structure, that seems problematic according to some other questions on Stack Overflow.

The "custom" field is totally random and this example only uses one, but there can be as many as possible. "conditions", "actions", "expressions" are fix fields then and so is the rest, but for the sake of this question I did not include the rest of the parsing.

The JSON file:

{
"custom": {
    "conditions": [
        {
            "id": "is-large-number",
            "scriptName": "IsLargeNumber",
            "highlight": true,
            "params": [
                {
                    "id": "number",
                    "type": "number"
                }
            ]
        }
    ],
    "actions": [
        {
            "id": "do-alert",
            "scriptName": "Alert",
            "highlight": true
        }
    ],
    "expressions": [
        {
            "id": "double",
            "expressionName": "Double",
            "scriptName": "Double",
            "highlight": true,
            "returnType": "number",
            "params": [
                {
                    "id": "number",
                    "type": "number"
                }
            ]
        }
    ]
}
}

I need to parse that into my own classes. Parsing into a java Object works like a charm, but I need to modify the data before dumping them back into a new JSON file, so using my own classes.

So I started by creating my own serializer:

public class ACESDeserializer implements JsonDeserializer<JSONACEs>{
    public JSONACEs deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        Map<String, JSONACEsCategory> nodes = new HashMap<>();
        JsonObject categories = json.getAsJsonObject();
        for (Map.Entry<String, JsonElement> category : categories.entrySet()) {
            String categoryName = category.getKey();
            JsonElement categoryData = category.getValue();
            JSONACEsCategory node = context.deserialize(categoryData, JSONACEsCategory.class);
            nodes.put(categoryName, node);
        }
        return new JSONACEs(nodes);
        // https://stackoverflow.com/questions/10668452/parsing-a-json-file-with-gson
    }
}

Loading is made like this:

private void loadACESJSON() {
    final GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(JSONACEs.class, new ACESDeserializer());
    final Gson gson = builder.setPrettyPrinting().create();
    try {
        final JsonReader reader = new JsonReader(new FileReader("src/main/resources/c3-plugin-sdk-v1/aces.json"));
        _JSONACEs = gson.fromJson(reader, JSONACEs.class);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println(gson.toJson(_JSONACEs));
}

This is my "container" class, JSONACEs, with a map as the "custom" field is random:

public class JSONACEs {
    private Map<String, JSONACEsCategory> _categories;

    public JSONACEs(Map<String, JSONACEsCategory> nodes) {
        _categories = nodes;
    }
}

This is the object itself, JSONACEsCategory, empty because I can't get the first part to work:

public class JSONACEsCategory {

}

Running this app outputs:

{
  "_categories": {
    "custom": {}
  }
}

Where it should output

{
  "custom": {}
}

As you can see, "_categories" is dumped, and this is wrong. It should dump "custom" directly as a child of the main JSON object.

Edit

Added a getter for the map in JSONSACEs and outputting it to the console returns:

{custom=com.psycho.c3plugen.model.JSONACEsCategory@25733d8}

So technically it looks okay. So my guess is I need to write my own serializer also then? Anybody could explain how I would do this for it to output correctly?

Upvotes: 2

Views: 819

Answers (1)

Psychokiller1888
Psychokiller1888

Reputation: 650

The solution is quite simple, as pointed by RC in the comments:

Simple serialize using

gson.toJson(_JSONACEs.getCategories());

Instead of

gson.toJson(_JSONACEs);

Upvotes: 1

Related Questions