首先,我有一个非常简单的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" }
然后为了使这样的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
}
现在我可以为节点设置更多数据:
Node node = new Node();
node.setText("Hello");
node.setData("to", "The world");
但是Gson会忽略“to”,结果仍然是{ text: "Hello" }
。我希望它是:{ text: "Hello", to: "The world" }
有没有办法为类型WithData
编写一个序列化程序,所有类扩展它不仅会为json生成自己的属性,还会生成map
中的数据?
我尝试实现自定义序列化程序,但失败了,因为我不知道如何让Gson首先序列化属性,然后是地图中的数据。
答案 0 :(得分: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;
};
}
然后使用GsonBuilder
转换它:
Gson gson = new GsonBuilder().
registerTypeAdapter(Node.class, new NodeSerializer()).create();
Tree tree = new Tree();
tree.addNode(node1);
tree.addNode(node2);
gson.toJson(tree);
然后树中的节点将按照我的预期进行转换。唯一无聊的是我每次都需要创建一个特殊的Gson
。
答案 1 :(得分:4)
实际上,您应该期望Node:WithData
序列化为
{
"text": "Hello",
"map": {
"to": "the world"
}
}
(打开“漂亮的打印”)
当我尝试你的例子时,我能够获得序列化。这是我的确切代码
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
public class Class1 {
public static void main(String[] args) throws MalformedURLException {
GsonBuilder gb = new GsonBuilder();
Gson g = gb.setPrettyPrinting().create();
Node n = new Node();
n.setText("Hello");
n.setData("to", "the world");
System.out.println(g.toJson(n));
}
private static 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); }
}
private static class Node extends WithData {
private String text;
public Node() { }
public String getText() {return text;}
public void setText(String text) {this.text = text;}
}
}
我正在使用JDK(javac)进行编译 - 这很重要,因为其他编译器(包含在某些IDE中的编译器)可能会删除Gson在优化或混淆过程中所依赖的信息。
以下是我使用的编译和执行命令:
“C:\ Program Files \ Java \ jdk1.6.0_24 \ bin \ javac.exe”-classpath gson-2.0.jar Class1.java
“C:\ Program Files \ Java \ jdk1.6.0_24 \ bin \ java.exe”-classpath .; gson-2.0.jar Class1
出于本次测试的目的,我将Gson jar文件放在与测试类文件相同的文件夹中。
请注意,我正在使用Gson 2.0; 1.x可能表现不同。
您的JDK可能安装在与我不同的位置,因此如果您使用这些命令,请务必根据需要调整JDK的路径。