用GSON解析课堂

时间:2017-11-06 10:16:18

标签: java json gson

我尝试使用 GSON 解析特定的JSON文件。到目前为止,它运行良好,因为我处理的所有JSON都具有数据属性。

但是我偶然发现了这个数据结构,根据StackOverflow上的其他一些问题,这似乎有问题。

"自定义" 字段是完全随机的,此示例仅使用一个,但可以尽可能多。 "条件","行动","表达"然后是修复字段,其余部分也是如此,但为了这个问题,我没有包括其余的解析。

JSON文件:

{
"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"
                }
            ]
        }
    ]
}
}

我需要将它解析为我自己的类。解析为java 对象就像魅力一样,但我需要在将数据转储回新的JSON文件之前修改数据,因此使用我自己的类。

所以我开始创建自己的序列化器:

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
    }
}

加载是这样的:

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));
}

这是我的&#34;容器&#34; class,JSONACEs,地图为&#34; custom&#34; 字段是随机的:

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

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

这是对象本身JSONACEsCategory,因为我无法使第一部分工作,所以它是空的:

public class JSONACEsCategory {

}

运行此应用输出:

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

应该输出的地方

{
  "custom": {}
}

如您所见,&#34; _categories&#34; 被转储,这是错误的。它应该直接将&#34; custom&#34; 转储为主JSON对象的子项。

任何帮助?

修改

在JSONSACEs中为地图添加了一个getter,并将其输出到控制台返回:

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

技术上看起来还不错。所以我的猜测是我还需要编写自己的序列化器吗?任何人都可以解释我如何才能正确输出?

RC的

解决方案

实际上,它只需要:

gson.toJson(_JSONACEs.getCategories())

1 个答案:

答案 0 :(得分:1)

解决方案非常简单,正如RC在评论中指出的那样:

使用

进行简单序列化
gson.toJson(_JSONACEs.getCategories());

而不是

gson.toJson(_JSONACEs);