Jackson或Gson使用mapKey作为实体对实体进行序列化/反序列化

时间:2018-11-07 13:07:13

标签: java serialization jackson gson deserialization

我的Node类

public class Node<T> {
    private T data;
    private Node<T> parent;
    private HashMap<Node<T>, String> children = new HashMap<>();
}

我的州立班级

public class State {
    private String name;
    private Boolean endState;
}

我的树类

public class Tree<T> {
    private Node<T> root;
    public Tree() {
}

public Tree(T rootData) {
    root = new Node<T>();
    root.setData(rootData);
}

public Node<T> getRoot() {
    return root;
}

我的主班

public class Main {
    public static void main(String[] args) throws IOException {
        Tree<State> stateMachine = new Tree<>(new State("q1", false));
        Node<State> q2 = new Node<>(new State("q2", true), stateMachine.getRoot());
        stateMachine.getRoot().addChild(q2, "a");
        stateMachine.getRoot().addChild(stateMachine.getRoot(), "a");

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        new ObjectMapper().writer().writeValue(os, stateMachine);
        String json = os.toString();
        os.close();

        System.out.println(json);
    }
}

我得到的输出是

{
  "root":{
    "data":{
      "name":"q1",
      "endState":false
    },
    "parent":null,
    "children":{
      "entity.Node@7adf9f5f":"a",
      "entity.Node@85ede7b":"a"
    }
  }
}

我不确定如何避免遇到无限递归并完全序列化/反序列化我的对象。

1 个答案:

答案 0 :(得分:0)

根据Json specification,Json字符串中的键必须为字符串。因此,首先您必须为地图创建自定义序列化程序。当然,您还希望对其进行反序列化,因此您也将需要自定义反序列化器。

然后将存在下一个问题:在反序列化期间,您想对所有出现的相同String使用相同的“键”对象。因此,您必须找到已经实例化的键。如果将所有节点存储在列表中,而不是使用Node对象本身作为键,则最简单的方法是使用其在列表中的位置。

这样,键可以是整数的字符串表示形式,并且您还可以轻松创建自定义反序列化。