Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通用树的自定义Jackson序列化程序_Java_Json_Generics_Jackson - Fatal编程技术网

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

Java 通用树的自定义Jackson序列化程序,java,json,generics,jackson,Java,Json,Generics,Jackson,假设我有一个用Java实现的参数化树,如下所示: public class Tree<E> { private static class Node { E element; List<Node> children. } Node root; //... You get the idea. } public class Tree<E> { private static class Node {

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

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

   Node root;

   //... You get the idea.
}
public class Tree<E> {
   private static class Node {

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

   @JsonUnwrapped
   Node root;

   //... You get the idea.
}
因此,最后,地理层次结构如下所示:

public class Geography extends Tree<GeoElement> {}
这种JSON呈现不好,因为它包含树和节点类中不必要的构件,即“根”和“元素”。我需要的是:

{
“名称”:“拉丁美洲”,
“类型”:“大陆”
“儿童”:[
{
“名称”:“巴西”,
“类型”:“国家”
“儿童”:[
//…巴西的州名单
]
},
{
“名称”:“阿根廷”,
“类型”:“国家”
“儿童”:[
//……阿根廷的国家名单
]
}
]
}

非常感谢您的帮助-Igor.

或许可以这样使用
@JsonValue

public class Tree<E> {
  @JsonValue
  Node root;
}
公共类树{
@JsonValue
节根;
}

如果只需“展开”树即可删除
元素
类型,一种可能是更改结构,使名称和类型直接包含在每个节点中:

public class TreeGeo {
   private static class Node {
      String name;
      String type;
      List<Node> children.
   }

   Node root;
}
公共类树{
私有静态类节点{
字符串名;
字符串类型;
列出孩子们。
}
节根;
}

要删除
根目录
类型,我不知道。我想你可以从jsonObject中提取一个子对象,但我对Jackson知之甚少。但是,您可以给它一个更好的名称,如
world
,或者通过一些字符串操作手动删除结果字符串。

您最好的选择是为您的对象构建并注册一个自定义序列化程序

定义序列化程序:

public class NodeSerializer extends StdSerializer<Node> {
以及
节点串行化器的内部

@Override
    public void serialize(
      Node node, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException {

        jgen.writeStartObject();
        jgen.writeStringField("name", node.element.name);

        jgen.writeStringField("type", node.element.type);
        //Process children
        serializeFields(node, jgen, provider);
        jgen.writeEndObject();
    }
这个通用框架将允许您控制如何序列化元素。您可能还需要
@JsonIgnore
节点内的
元素
对象
,因为您的自定义序列化程序负责将该信息推送到生成的JSON中。网上有很多关于自定义序列化程序和重写默认JSON导出的内容

您可以使用树实现的序列化程序以类似的方式除去root

如果不想在类上注册序列化程序,也可以使用
ObjectMapper
一次注册一个序列化程序:

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule();
module.addSerializer(Node.class, new NodeSerializer());
mapper.registerModule(module);

String serialized = mapper.writeValueAsString(tree);
注释方法将全局应用。这种方法允许对自定义序列化程序的使用方式/位置进行某种控制。

您需要的是

用于指示属性应序列化为“展开”的注释;也就是说,如果将其序列化为JSON对象,则其属性将作为其包含对象的属性包含

将此注释添加到
节点
类的
元素
字段的
字段,如下所示:

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

   Node root;

   //... You get the idea.
}
public class Tree<E> {
   private static class Node {

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

   @JsonUnwrapped
   Node root;

   //... You get the idea.
}

谢谢你的建议,斯里尼瓦斯。它不起作用,因为我不想忽略节点,只想丢弃节点包装器。你找到解决方案了吗?如果找到了,请update@anonStaxMan提供的解决方案不起作用吗?我在类中没有根节点。节点->数据,列表结构。在这里,我必须创建一个单独的节点序列化程序,并编写递归代码来完成它,我认为这是行不通的。它只需打开外部
根对象。它不会展开
元素
对象。
{
    "name": "Latin America",
    "type": "Continent",
    "children": [{
        "name": "Brazil",
        "type": "Country",
        "children": []
    }, {
        "name": "Argentina",
        "type": "Country",
        "children": []
    }]
}