首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用jackson序列化递归对象,直到达到一定深度

使用jackson序列化递归对象,直到达到一定深度
EN

Stack Overflow用户
提问于 2020-01-08 04:36:36
回答 1查看 913关注 0票数 3

我有一个需要序列化的树对象结构,我希望每次都能够使用jackson (或任何其他库--我是开放的)基于参数来控制序列化的深度。

我的类是这样的:

代码语言:javascript
运行
复制
class Node {
    ...
    private String id;
    private Node child;
    ...
}

这里有两个序列化的json示例,我希望基于深度级别获得它们。

深度级别设置为3

代码语言:javascript
运行
复制
{
  "id": "A",
  "child": {
    "id": "B",
    "child": {
      "id": "C",
      "child": {}
    }
  }
}

深度级别设置为2

代码语言:javascript
运行
复制
{
  "id": "A",
  "child": {
    "id": "B",
    "child": {}
  }
}

有没有办法控制递归对象中序列化的深度?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-09 05:55:35

您需要实现自定义序列化程序,在其中您需要计算已经处理的Node对象的数量。对于每个序列化过程,我们需要提供max depth值,并在每次发现Node类时递减该值。示例实现:

代码语言:javascript
运行
复制
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializer;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

public class JsonApp {

    public static void main(String[] args) throws IOException {
        Node nodeD = new Node("D", null);
        Node nodeC = new Node("C", nodeD);
        Node nodeB = new Node("B", nodeC);
        Node nodeA = new Node("A", nodeB);

        for (int i = 0; i < 4; i++) {
            System.out.println("Depth: " + i);
            System.out.println(serialiseWithDepth(nodeA, i));
        }
    }

    private static ObjectMapper mapper = JsonMapper.builder()
            .enable(SerializationFeature.INDENT_OUTPUT)
            .addModule(createNodeModule())
            .build();

    private static String serialiseWithDepth(Node node, int maxDepth) throws JsonProcessingException {
        ObjectWriter writer = mapper.writerFor(Node.class)
                .withAttribute(NodeDepthBeanSerializer.DEPTH_KEY, new AtomicInteger(maxDepth));

        return writer.writeValueAsString(node);
    }

    private static SimpleModule createNodeModule() {
        SimpleModule nodeModule = new SimpleModule("NodeModule");
        nodeModule.setSerializerModifier(new BeanSerializerModifier() {
            @Override
            public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
                if (beanDesc.getBeanClass() == Node.class) {
                    return new NodeDepthBeanSerializer((BeanSerializerBase) serializer);
                }
                return super.modifySerializer(config, beanDesc, serializer);
            }
        });
        return nodeModule;
    }
}

class NodeDepthBeanSerializer extends BeanSerializer {

    public static final String DEPTH_KEY = "maxDepthSize";

    public NodeDepthBeanSerializer(BeanSerializerBase src) {
        super(src);
    }

    @Override
    protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException {
        AtomicInteger depth = (AtomicInteger) provider.getAttribute(DEPTH_KEY);
        if (depth.decrementAndGet() >= 0) {
            super.serializeFields(bean, gen, provider);
        }
    }
}

上面的代码打印:

代码语言:javascript
运行
复制
Depth: 0
Node{id='A', child=Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}}} => 0
{ }
Depth: 1
Node{id='A', child=Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}}} => 1
Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}} => 0
{
  "id" : "A",
  "child" : { }
}
Depth: 2
Node{id='A', child=Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}}} => 2
Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}} => 1
Node{id='C', child=Node{id='D', child=null}} => 0
{
  "id" : "A",
  "child" : {
    "id" : "B",
    "child" : { }
  }
}
Depth: 3
Node{id='A', child=Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}}} => 3
Node{id='B', child=Node{id='C', child=Node{id='D', child=null}}} => 2
Node{id='C', child=Node{id='D', child=null}} => 1
Node{id='D', child=null} => 0
{
  "id" : "A",
  "child" : {
    "id" : "B",
    "child" : {
      "id" : "C",
      "child" : { }
    }
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59635711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档