You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Jackson序列化自定义TreeNodeLabel生成指定结构的JSONObject

如何将TreeNodeLabel对象转换为指定的嵌套JSON结构

你遇到的问题其实很典型:默认的Jackson注解没办法直接把children列表转换成以子节点name为键的嵌套结构,也没法自动把prop里的键值对直接平铺在当前节点下。要生成你想要的JSON格式,自定义序列化器是最直接的解决方案。

第一步:理解需求对应关系

先明确你的TreeNodeLabel结构和目标JSON的映射逻辑:

  • 节点的prop里的键值对 → 直接作为当前JSON对象的键值对
  • 节点的children列表 → 每个子节点以自身name为键,子节点的内容(包含它的prop和子节点)作为对应值
  • parent字段需要忽略,避免循环引用

第二步:自定义Jackson序列化器

写一个继承JsonSerializer<TreeNodeLabel>的类,手动控制序列化逻辑:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.util.Map;

public class TreeNodeLabelSerializer extends JsonSerializer<TreeNodeLabel> {

    @Override
    public void serialize(TreeNodeLabel node, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        
        // 先写入当前节点prop中的所有键值对
        if (node.getProp() != null) {
            for (Map.Entry<String, String> entry : node.getProp().entrySet()) {
                gen.writeStringField(entry.getKey(), entry.getValue());
            }
        }
        
        // 递归处理子节点,以子节点name为键,序列化子节点内容
        if (node.getChildren() != null && !node.getChildren().isEmpty()) {
            for (TreeNodeLabel child : node.getChildren()) {
                gen.writeFieldName(child.getName());
                serialize(child, gen, serializers);
            }
        }
        
        gen.writeEndObject();
    }
}

第三步:修改TreeNodeLabel类配置

给你的类加上序列化器注解,并忽略parent字段防止循环引用:

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.List;
import java.util.Map;

@JsonSerialize(using = TreeNodeLabelSerializer.class)
public class TreeNodeLabel { 
    @JsonIgnore
    TreeNodeLabel parent; 
    List<TreeNodeLabel> children; 
    Map<String, String> prop; 
    String name; 

    // 必须添加getter方法,序列化器需要访问这些字段
    public TreeNodeLabel getParent() { return parent; }
    public void setParent(TreeNodeLabel parent) { this.parent = parent; }
    public List<TreeNodeLabel> getChildren() { return children; }
    public void setChildren(List<TreeNodeLabel> children) { this.children = children; }
    public Map<String, String> getProp() { return prop; }
    public void setProp(Map<String, String> prop) { this.prop = prop; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

第四步:测试序列化效果

用一个示例代码构建你的TreeNodeLabel结构,然后序列化:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LabelSerializerTest {
    public static void main(String[] args) throws Exception {
        // 构建login节点的errors子节点
        Map<String, String> errorsProp = new HashMap<>();
        errorsProp.put("loginRequired", "Email requis");
        errorsProp.put("loginFormat", "Format de l'email incorrect");
        TreeNodeLabel errorsNode = new TreeNodeLabel();
        errorsNode.setName("errors");
        errorsNode.setProp(errorsProp);

        // 构建login节点
        Map<String, String> loginProp = new HashMap<>();
        loginProp.put("login", "Me connecter");
        loginProp.put("label", "Connectez-vous");
        TreeNodeLabel loginNode = new TreeNodeLabel();
        loginNode.setName("login");
        loginNode.setProp(loginProp);
        loginNode.setChildren(List.of(errorsNode));

        // 构建auth节点
        Map<String, String> authProp = new HashMap<>();
        authProp.put("myChallenges", "Visualiser vos défis");
        authProp.put("myMessages", "Accéder à la messagerie");
        TreeNodeLabel authNode = new TreeNodeLabel();
        authNode.setName("auth");
        authNode.setProp(authProp);
        authNode.setChildren(List.of(loginNode));

        // 构建根data节点
        TreeNodeLabel dataNode = new TreeNodeLabel();
        dataNode.setName("data");
        dataNode.setChildren(List.of(authNode));

        // 序列化输出
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(dataNode);
        System.out.println(json);
    }
}

运行这段代码,就能得到和你期望结构完全一致的JSON了。

内容的提问来源于stack exchange,提问作者Aléxis Bernard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:43:14