java请求接口接收树形结构数据丢失问题

背景:

我们前后端交互可能会涉及到树形结构数据

1,大多数设计,定义树结构基类

package com.yw.framework.tree;
import lombok.Data;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 功能描述: <结构树>
 * 〈〉
 *
 * @Author: zl
 * @Date: 2021/10/15 9:15
 */
@Data
public class Node {

    
    protected String id;

    protected String parentId;

    protected String name;

    protected List<Node> children = new ArrayList<>();

    protected String description;

    protected int rank = 0;

}

2,不同父结构数据类型继承即可

@Data
public static class AbilityNode extends Node {

    private Double weight;

    private List<AbilityQuotaResp> abilityQuotaRespList;

}

3,构建工具类

package com.yw.framework.tree;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author zl
 * @Description 树形构造处理工具类
 *
 * @Date 2021/6/1 9:12
 */
public class BuildTree {

    /**
     * 功能描述: <生成树结构>
     * 〈〉
     *
     * @Param: [T]
     * @Author: zl
     * @Date: 2021/6/1 9:10
     */
    public static List<Node> buildTree(List<? extends Node> nodeList) {
        List<Node> nodes = new ArrayList<>();
        for (Node node : nodeList) {
            String parentId = node.getParentId();
            if (parentId == null || "".equals(parentId)) {
                nodes.add(node);
                continue;
            }
            for (Node parent : nodeList) {
                if (parent.getId().equals(parentId)) {
                    List<Node> parentList = parent.getChildren();
                    if (parentList == null) {
                        parentList = new ArrayList<>();
                        parentList.add(node);
                        parent.setChildren(parentList);
                    } else {
                        parentList.add(node);
                    }
                }
            }
        }
        return nodes;
    }


    /**
     * 给树节点设置层级rank标识
     *
     * @param nodes
     */
    public static void setLevel(List<Node> nodes) {
        for (Node node : nodes) {
            String parentId = node.getParentId();
            if (parentId == null || "".equals(parentId)) {
                node.setRank(1);
                dfsLevel(node);
            }
        }

    }

    /**
     * 递归遍历节点数
     * @param node
     */
    public static void dfsLevel(Node node) {
        List<Node> children = node.getChildren();
        if (children!=null) {
            for (Node child : children) {
                child.setRank(node.getRank() + 1);
                dfsLevel(child);
            }
        }

    }

    /**
     * 获取树的最大层级
     *
     * @param nodes
     * @return
     */
    public static int maxLevel(List<Node> nodes,int maxlevel) {
        for (Node node : nodes) {
            maxlevel = Math.max(node.getRank(), maxlevel);
            if (node.getChildren()!=null) {
                return maxLevel(node.getChildren(), maxlevel);
            }
        }
        return maxlevel;
    }

    /**
     * 获取树的某一层级所有节点
     *
     * @param nodes
     * @param level
     * @return
     */
    public static List<Node> getLevelNode(List<Node> nodes, int level, List<Node> nodeList) {
        for (Node node : nodes) {
            if (node.getRank() == level) {
                nodeList.add(node);
            }
            if (node.getChildren()!=null) {
                getLevelNode(node.getChildren(), level, nodeList);
            }
        }
        return nodeList;
    }

    /**
     * 获取树的所有叶子节点
     *
     * @param nodes
     * @return
     */
    public static List<Node> getLeafNode(List<? extends Node> nodes, List<Node> leafNode) {

        for (Node node : nodes) {
            if (node.getChildren() == null || node.getChildren().size() == 0) {
                leafNode.add(node);
            } else {
                getLeafNode(node.getChildren(), leafNode);
            }
        }
        return leafNode;
    }

    /**
     * 删除给定的叶子节点
     * @param nodes
     * @param ids
     * @param deleteSize
     * @return
     */
    public static int deleteLeafNode(List<Node> nodes, String[] ids, int deleteSize) {

        boolean b = nodes.removeIf(node -> {
            if ((node.getParentId() == null || "".equals(node.getParentId())) && (node.getChildren() == null || node.getChildren().size() == 0)) {
                boolean isDelete = true;
                for (int i = 0; i < ids.length; i++) {
                    if (ids[i].equals(node.getId())) {
                        isDelete = false;
                        break;
                    }
                }
                return isDelete;
            }
            return false;

        });
        if (b) {
            deleteSize++;
        }

        for (Node node : nodes) {
            if (node.getChildren() == null || node.getChildren().size() == 0) {
                boolean isDelete = true;
                for (int i = 0; i < ids.length; i++) {
                    if (ids[i].equals(node.getId())) {
                        isDelete = false;
                    }
                }
                if (isDelete) {
                    deleteSize++;
                    for (Node parent : nodes) {
                        if (parent.getId().equals(node.getParentId())) {
                            parent.getChildren().remove(node);
                            break;
                        }
                    }
                }
            } else {
                return deleteLeafNode(node.getChildren(), ids, deleteSize);
            }
        }
        return deleteSize;
    }

}

4,这样作为后端返回给前端设计没有问题

5,但是,如果是接收前端树形结构就会出现问题,接收的树结构的子节点数据都没有继承类中定义的数据

例如这样一个结构数据:

    "abilityNodeList": [
      {
        "id": "1",
        "elementId": "能力",
        "parentId": "",
        "name": "侦查能力",
        "children": [
          {
            "id": "5d0c25bfb00f4120bb56ecee1f16a20b","parentId": "1",
            "name": "111",
            "children": [],
            "description": "111",
            "rank": 0,
            "weight": 0.2,
            "abilityQuotaRespList": []
          },
          {
            "id": "19859ac711964779aabf453fae7aa890","parentId": "1",
            "name": "222",
            "children": [],
            "description": "",
            "rank": 0,
            "weight": 0.2,
            "abilityQuotaRespList": []
          }
        ],
        "description": "侦查能力",
        "rank": 0,
        "weight": 0.2,
        "abilityQuotaRespList": [
          {
            "id": "6",
            "name": "能力指标6",
            "weight": 0.8,
            "contribution": 0
          },
          {
            "id": "7",
            "name": "能力指标7",
            "weight": 0.6,
            "contribution": 0
          }
        ]
      },
      {
        "id": "3","parentId": "",
        "name": "预警能力",
        "children": [],
        "description": "预警能力",
        "rank": 0,
        "weight": 0.2,
        "abilityQuotaRespList": []
      },
      {
        "id": "2","parentId": "",
        "name": "通信能力",
        "children": [],
        "description": "通信能力",
        "rank": 0,
        "weight": 0.2,
        "abilityQuotaRespList": [
          {
            "id": "3",
            "name": "海上通信",
            "weight": 0.4,
            "contribution": 0.1
          },
          {
            "id": "4",
            "name": "地面通信",
            "weight": 0.4,
            "contribution": 0.1
          }
        ]
      }
    ]

请求过来之后,除了根节点数据,所有子节点都没有weight和abilityQuotaRespList属性以及数据子节点默认还是基类(Node)类型

6,最后,请求数据 树形结构类型不能用继承

可这样直接设计,即定制化设计:

package com.yw.module.abilitycontribution.resp;

import com.yw.module.core.InputOutcomeData.SystemAbilityInputNodeData;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author zl
 * @Description
 * @Date 2021/10/15 9:16
 */
@Data
public class AbilityNode {

    protected String id;

    protected String parentId;

    protected String name;

    protected List<AbilityNode> children = new ArrayList<>();


    protected int rank = 0;


    private Double weight;


    private List<AbilityQuotaResp> abilityQuotaRespList;

    @Data
    public static class AbilityQuotaResp{
        private String id;

        private String name;
    }
}
心有所想,必有回响
原文地址:https://www.cnblogs.com/zhulei2/p/15410356.html