用于通用树的自定义Jackson序列化程序

For*_*ght 16 java generics json jackson

假设我有一个用Java实现的参数化树,如下所示:

public class Tree<E> {
   private static class Node {
      E element;
      List<Node> children.
   }

   Node root;

   //... You get the idea.
}
Run Code Online (Sandbox Code Playgroud)

这里的想法是上面的实现仅涉及树的拓扑,但是不知道将通过实例化存储在树中的元素的任何信息.

现在,说我希望我的树元素是地理位置.它们在树木中组织的原因是因为大陆包含国家,国家包含州或省,等等.为简单起见,地理位置具有名称和类型:

public class GeoElement { String name; String type; }
Run Code Online (Sandbox Code Playgroud)

最后,地理层次结构如下所示:

public class Geography extends Tree<GeoElement> {}
Run Code Online (Sandbox Code Playgroud)

现在到杰克逊序列化.假设Jackson序列化程序可以看到字段,则此实现的直接序列化将如下所示:

{
   "root": {
      "element": {
         "name":"Latin America",
         "type":"Continent"
      }
      "children": [
          {
             "element": {
                "name":"Brazil",
                "type":"Country"
             },
             "children": [
                 // ... A list of states in Brazil
             ]
          },
          {
             "element": {
                "name":"Argentina",
                "type":"Country"
             },
             "children": [
                 // ... A list of states in Argentina
             ]
          }
      ]
   }
Run Code Online (Sandbox Code Playgroud)

这种JSON渲染并不好,因为它包含来自Tree和Node类的不必要的工件,即"root"和"element".我需要的是这样的:

{
   "name":"Latin America",
   "type":"Continent"
   "children": [
       {
          "name":"Brazil",
          "type":"Country"
          "children": [
             // ... A list of states in Brazil
          ]
       },
       {
          "name":"Argentina",
          "type":"Country"
          "children": [
             // ... A list of states in Argentina
          ]
       }
   ]
}
Run Code Online (Sandbox Code Playgroud)

任何帮助都非常感谢.-Igor.

Pan*_*hal 7

你需要的是什么@JsonUnwrapped.

用于表示属性应序列化为"未包装"的注释; 也就是说,如果它被序列化为JSON对象,则其属性将作为其包含Object的属性包含在内

这个注释添加到root的领域Treeelement领域的Node课程如下:

public class Tree<E> {
   private static class Node {

      @JsonUnwrapped
      E element;
      List<Node> children.
   }

   @JsonUnwrapped
   Node root;

   //... You get the idea.
}
Run Code Online (Sandbox Code Playgroud)

它会给你你想要的输出:

{
    "name": "Latin America",
    "type": "Continent",
    "children": [{
        "name": "Brazil",
        "type": "Country",
        "children": []
    }, {
        "name": "Argentina",
        "type": "Country",
        "children": []
    }]
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 5

也许@JsonValue像这样使用:

public class Tree<E> {
  @JsonValue
  Node root;
}
Run Code Online (Sandbox Code Playgroud)

如果您只需要“解开”您的树?