如何使用google-gson将这样的自定义类型序列化为json?

Fre*_*ind 0 serialization json gson

首先,我有一个非常简单的java bean,可以很容易地序列化为json:

class Node {
    private String text;
    // getter and setter
}

Node node = new Node();
node.setText("Hello");

String json = new Gson().toJson(node);
// json is { text: "Hello" }
Run Code Online (Sandbox Code Playgroud)

然后为了使这样的bean有一些动态值,所以我创建了一个"WithData"基类:

Class WithData {
    private Map<String, Object> map = new HashMap<String, Object>();
    public void setData(String key, Object value) { map.put(key, value); }
    public Object getData(String key) = { return map.get(key); }
}

class Node extends WithData {
    private String text;
    // getter and setter
}
Run Code Online (Sandbox Code Playgroud)

现在我可以为节点设置更多数据:

Node node = new Node();
node.setText("Hello");
node.setData("to", "The world");
Run Code Online (Sandbox Code Playgroud)

但是Gson会忽略"to",结果仍然存在{ text: "Hello" }.我希望它是:{ text: "Hello", to: "The world" }

有没有办法为类型编写一个序列化器WithData,所有类扩展它不仅会生成自己的属性到json,还会生成map

我尝试实现自定义序列化程序,但失败了,因为我不知道如何让Gson首先序列化属性,然后是map中的数据.

Fre*_*ind 6

我现在做的是创建一个自定义序列化器:

public static class NodeSerializer implements JsonSerializer<Node> {
    public JsonElement serialize(Node src,
            Type typeOfSrc, JsonSerializationContext context) {
        JsonObject obj = new JsonObject();
        obj.addProperty("id", src.id);
        obj.addProperty("text", src.text);
        obj.addProperty("leaf", src.leaf);
        obj.addProperty("level", src.level);
        obj.addProperty("parentId", src.parentId);
        obj.addProperty("order", src.order);
        Set<String> keys = src.getDataKeys();
        if (keys != null) {
            for (String key : keys) {
                obj.add(key, context.serialize(src.getData(key)));
            }
        }
        return obj;
    };
}
Run Code Online (Sandbox Code Playgroud)

然后用GsonBuilder它来转换它:

Gson gson = new GsonBuilder().
    registerTypeAdapter(Node.class, new NodeSerializer()).create();

Tree tree = new Tree();
tree.addNode(node1);
tree.addNode(node2);

gson.toJson(tree);
Run Code Online (Sandbox Code Playgroud)

然后树中的节点将按照我的预期进行转换.唯一无聊的事情是我Gson每次都需要创造一个特殊的东西.