Java实现级联下拉结构的示例代码(java二级联动下拉列表怎么实现)

网友投稿 844 2022-07-27


目录前言构建统一返回下拉结构构建集合<对象>转下拉树工具类构建List转下拉或下拉树的工具类

前言

在开发过程中,会遇到很多的实体需要将查出的数据处理为下拉或者级联下拉的结构,提供给前端进行展示。

在数据库查出的结构中,可能是集合<实体类>的结构,也有可能是List的结构。

在下拉或者级联下拉的节点数据中,有时候还需要动态的携带其他的参数,已便于前端对某些数据的显示

如区域的级联下拉树中,需要携带经纬度的区域–在选择的时候在地图展示该区域

基于上面的业务场景,构建了下面的工具类,不当的地方请大家多多指教

注:在构建下拉树的时候,会存在父类id的判断,可能没有涵盖到你们的使用情况,自行修改添加

构建统一返回下拉结构

/**

* Treeselect树结构实体类

*

* @author gongl

*/

@ApiModel("下拉树结构")

public class TreeSelect implements Serializable {

private static final long serialVersionUID = 1L;

/**

* 节点ID

*/

@ApiModelProperty("节点id")

private String id;

/**

* 节点名称

*/

@ApiModelProperty("节点名")

private String label;

/**

* 下拉节点中携带数据

*/

@jsonInclude(JsonInclude.Include.NON_EMPTY)

@ApiModelProperty("节点携带数据")

private Map dataMap;

/**

* 子节点

*/

@JsonInclude(JsonInclude.Include.NON_EMPTY)

@ApiModelProperty("子节点集合")

private List children;

public TreeSelect() {

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getLabel() {

return label;

}

public void setLabel(String label) {

this.label = label;

}

public List getChildren() {

return children;

}

public void setChildren(List children) {

this.children = children;

}

public Map getDataMap() {

return dataMap;

}

public void setDataMap(Map dataMap) {

this.dataMap = dataMap;

}

构建集合<对象>转下拉树工具类

/**

* 下拉和级联下拉通用生成工具类

*

* @Author gongl

* @Create 2022-01-12

*/

public class TreeSelectUtils {

private static final Logger log = LoggerFactory.getLogger(TreeSelectUtils.class);

/**

* 默认id名称

*/

public static final String ID = "id";

/**

* 默认父类id名称

*/

public static final String PARENT = "parentId";

/**

* 默认label名称

*/

public static final String LABEL = "name";

/**

* 单层下拉结构

*

* @param collection 目标集合

* @param id 节点编号字段

* @param label 节点名字段

* @param clazz 集合元素类型

* @param args 需要携带的参数

* @return 转换后的下拉结构 TreeSelect

*/

public static List singleTree(Collection collection, String id, String label,

Class> clazz, String... args) {

try {

if (collection == null || collection.isEmpty()) {

return null;

}

Field idField;

try {

idField = clazz.getDeclaredField(id);

} catch (NoSuchFieldException e1) {

idField = clazz.getSuperclass().getDeclaredField(id);

}

Field labelField;

try {

labelField = clazz.getDeclaredField(label);

} catch (NoSuchFieldException e1) {

labelField = clazz.getSuperclass().getDeclaredField(label);

}

idField.setAccessible(true);

labelField.setAccessible(true);

List list = new ArrayList<>();

for (E e : collection) {

TreeSelect select = new TreeSelect();

select.setId(String.valueOf(idField.get(e)));

select.setLabel(String.valueOf(labelField.get(e)));

list.add(select);

dynamicData(select, e, clazz, args);

}

idField.setAccessible(false);

labelField.setAccessible(false);

return list;

} catch (Exception e) {

log.error("单层下拉异常:", e);

e.printStackTrace();

return null;

}

}

/**

* 集合转树结构(默认树结构字段)

*

* @param collection 目标集合

* @param clazz 集合元素类型

* @param args 需要携带的参数

* @return 转换后的树形结构 TreeSelect

*/

public static List toTree(@NotNull Collection collection, @NotNull Class> clazz,

String... args) {

return toTree(collection, null, null, null, clazz, args);

}

/**

* 集合转树结构(自定义名称字段)

*

* @param collection 目标集合

* @param label 节点名字段

* @param clazz 集合元素类型

* @param args 需要携带的参数

* @return 转换后的树形结构 TreeSelect

*/

public static List toTree(@NotNull Collection collection, @NotEmpty String label,

@NotNull Class> clazz, String... args) {

return toTree(collection, null, null, label, clazz, args);

}

/**

* 集合转树结构(默认父类id字段为parentId,其他自定义)

*

* @param collection 目标集合

* @param id 节点编号字段

* @param label 节点名字段

* @param clazz 集合元素类型

* @param args 需要携带的参数

* @return 转换后的树形结构 TreeSelect

*/

public static List toTree(@NotNull Collection collection, @NotEmpty String id, @NotEmpty String label,

@NotNull Class> clazz, String... args) {

return toTree(collection, id, null, label, clazz, args);

}

/**

* 集合转树结构(自定义树结构的字段)

*

* @param collection 目标集合

* @param id 节点编号字段

* @param parent 父节点编号字段

* @param label 节点名字段

* @param clazz 集合元素类型

* @param args 需要携带的参数

* @return 转换后的树形结构 TreeSelect

*/

public static List toTree(@NotNull Collection collection, String id, String parent, String label,

http:// @NotNull Class> clazz, String... args) {

try {

if (collection == null || collection.isEmpty()) {

return null;

}

//可以默认名称

if (StringUtils.isEmpty(id)) {

id = ID;

}

if (StringUtils.isEmpty(parent)) {

parent = PARENT;

}

if (StringUtils.isEmpty(label)) {

label = LABEL;

}

//是对象

return collectionObj(collection, id, parent, label, clazz, args);

} catch (Exception e) {

log.error("多层下拉树异常:", e);

return null;

}

}

/**

* 集合对象的封装

*/

private static List collectionObj(@NotNull Collection collection, String id, String parent, String label,

@NotNull Class> clazz, String... args) throws NoSuchFieldException, IllegalAccessException {

// 初始化根节点集合

List list = new ArrayList<>();

// 获取 id 字段, 从当前对象或其父类

Field idField;

try {

idField = clazz.getDeclaredField(id);

} catch (NoSuchFieldException e1) {

idField = clazz.getSuperclass().getDeclaredField(id);

}

// 获取 parentId 字段, 从当前对象或其父类

Field parentField;

try {

parentField = clazz.getDeclaredField(parent);

} catch (NoSuchFieldException e1) {

parentField = clazz.getSuperclass().getDeclaredField(parent);

}

// 获取 label 字段, 从当前对象或其父类

Field labelField;

try {

labelField = clazz.getDeclaredField(label);

} catch (NoSuchFieldException e1) {

labelField = clazz.getSuperclass().getDeclaredField(label);

}

idField.setAccessible(true);

parentField.setAccessible(true);

labelField.setAccessible(true);

// 找出所有的根节点

for (E e : collection) {

Object parentId = parentField.get(e);

if (isParentNode(parentId, idField, collection)) {

TreeSelect select = new TreeSelect();

select.setId(String.valueOf(idField.get(e)));

select.setLabel(String.valueOf(labelField.get(e)));

list.add(select);

dynamicData(select, e, clazz, args);

}

}

// 依次添加子节点

for (TreeSelect select : list) {

addChild(select, collection, idField, parentField, labelField, clazz, args);

}

idField.setAccessible(false);

parentField.setAccessible(false);

labelField.setAccessible(false);

return list;

}

/**

* 添加跟随下拉的字段

*

* @param treeSelect 当前节点

* @param e

* @param clazz

* @param args 需要跟随的字段

* @throws IllegalAccessException

* @throws NoSuchFieldException

*/

private static void dynamicData(@NotNull TreeSelect treeSelect, @NotNull Object e, @NotNull Class clazz, String... args) throws IllegalAccessException, NoSuchFieldException {

if (args.length > 0) {

Map dataMap = new HashMap<>();

for (String arg : args) {

Field field;

try {

field = clazz.getDeclaredField(arg);

} catch (NoSuchFieldException e1) {

field = clazz.getSuperclass().getDeclaredField(arg);

}

field.setAccessible(true);

dataMap.put(arg, field.get(e));

field.setAccessible(false);

}

treeSelect.setDataMap(dataMap);

}

}

/**

* 为目标节点添加孩子节点

*

* @param node 目标节点

* @param collection 目标集合

* @param idField ID 字段

* @param parentField 父节点字段

* @param labelField 字节点字段

*/

private static void addChild(@NotNull TreeSelect node, @NotNull Collection collection,

@NotNull Field idField, @NotNull Field parentField, @NotNull Field labelField,

@NotNull Class> clazz, String... args) throws IllegalAccessException, NoSuchFieldException {

//父节点的id

String id = node.getId();

//子节点集合

List children = new ArrayList<>();

for (E e : collection) {

String parentId = String.valueOf(parentField.get(e));

if (id.equals(parentId)) {

// 将当前节点添加到目标节点的孩子节点

TreeSelect treeSelect = new TreeSelect();

treeSelect.setId(String.valueOf(idField.get(e)));

treeSelect.setLabel(String.valueOf(labelField.get(e)));

dynamicData(treeSelect, e, clazz, args);

children.add(treeSelect);

// 递归添加子节点

addChild(treeSelect, collection, idField, parentField, labelField, clazz, args);

}

}

node.setChildren(children);

}

/**

* 判断是否是根节点, 判断方式为:

* 1、父节点编号为空或为 0, 则认为是根节点

* 2、父节点在集合中不存在父节点

*

* @param parentId 父节点编号

* @return 是否是根节点

*/

private static boolean isParentNode(Object parentId, Field idField, @NotNull Collection collection) throws IllegalAccessException {

if (parentId == null) {

return true;

} else if (parentId instanceof String && (StringUtils.isEmpty(String.valueOf(parentId)) || parentId.equals("0"))) {

return true;

} else if (parentId instanceof Long && Long.valueOf(0).equals(parentId)) {

return true;

} else {

for (E e : collection) {

Object o = idField.get(e);

if (Objects.equals(o, parentId)) {

return false;

}

}

return true;

}

}

}

构建List转下拉或下拉树的工具类

/**

* 下拉和级联下拉通用生成工具类

*

* @Author gongl

* @Create 2022-01-12

*/

public class MapToTreeSelectUtils {

private static final Logger log = LoggerFactory.getLogger(MapToTreeSelectUtils.class);

/**

* 数据库默认父类id名称

*/

public static final String DB_PARENT = "parent_id";

/**

* 集合转树结构(自定义树结构的字段)

*

* @param collection 目标集合

* @param id 节点编号字段

* @param parent 父节点编号字段

* @param label 节点名字段

* @param args 需要携带的参数

* @return 转换后的树形结构 TreeSelect

*/

public static List mapToTree(String id, String parent, String label,

@NotNull List> collection, String... args) {

try {

if (collection == null || collection.isEmpty()) {

return new ArrayList<>();

}

//可以默认名称

if (StringUtils.isEmpty(id)) {

id = TreeSelectUtils.ID;

}

if (StringUtils.isEmpty(parent)) {

parent = DB_PARENT;

}

if (StringUtils.isEmpty(label)) {

label = TreeSelectUtils.LABEL;

}

return collectionMap(id, parent, label, collection, args);

} catch (Exception e) {

log.error("多层下拉树异常:", e);

return null;

}

}

/**

* 集合map的封裝

*/

private static List collectionMap(String id, String parent, String label,

@NotNull List> collection, String... args) throws IllegalAccessException, NoSuchFieldException {

List list = new ArrayList<>();

// 找出所有的根节点

for (Map next : collection) {

Object parentId = next.get(parent);

if (isParentNodeMap(parentId, id, collection)) {

TreeSelect select = new TreeSelect();

select.setId(String.valueOf(next.get(id)));

select.setLabel(String.valueOf(next.get(label)));

list.add(select);

dyhttp://namicData(select, next, args);

}

}

// 依次添加子节点

for (TreeSelect select : list) {

addChildMap(select, id, parent, label, collection, args);

}

return list;

}

/**

* 添加跟随下拉的字段

*

* @param treeSelect 当前节点

* @param e

* @param args 需要跟随的字段

* @throws IllegalAccessException

* @throws NoSuchFieldException

*/

private static void dynamicData(@NotNull TreeSelect treeSelect, @NotNull Map e, String... args) throws IllegalAccessException, NoSuchFieldException {

if (args.length > 0) {

Map dataMap = new HashMap<>();

for (String arg : args) {

dataMap.put(arg, e.get(arg));

}

treeSelect.setDataMap(dataMap);

}

}

/**

* 为目标节点添加孩子节点

*

* @param node 目标节点

* @param collection 目标集合

* @param id ID 字段

* @param parent 父节点字段

* @param label 字节点字段

*/

private static void addChildMap(@NotNull TreeSelect node, String id, String parent, String label,

@NotNull List> collection,

String... args) throws IllegalAccessException, NoSuchFieldException {

//父节点的id

String nodeId = node.getId();

//子节点集合

List children = new ArrayList<>();

for (Map e : collection) {

String parentId = String.valueOf(e.get(parent));

if (nodeId.equals(parentId)) {

// 将当前节点添加到目标节点的孩子节点

TreeSelect treeSelect = new TreeSelect();

treeSelect.setId(String.valueOf(e.get(id)));

treeSelect.setLabel(String.valueOf(e.get(label)));

dynamicData(treeSelect, e, args);

children.add(treeSelect);

node.setChildren(children);

// 递归添加子节点

addChildMap(treeSelect, id, parent, label, collection, args);

}

}

}

/**

* 判断是否是根节点, 判断方式为:

* 1、父节点编号为空或为 0, 则认为是根节点

* 2、父节点在集合中不存在父节点

*

* @param parentId 父节点编号

* @return 是否是根节点

*/

private static boolean isParentNodeMap(Object parentId, String id, @NotNull List> collection) {

if (parentId == null) {

return true;

} else if (parentId instanceof String && (StringUtils.isEmpty(String.valueOf(parentId)) || parentId.equals("0"))) {

return true;

} else if (parentId instanceof Long && Long.valueOf(0).equals(parentId)) {

return true;

} else {

for (Map e : collection) {

Object o = e.get(id);

if (Objects.equals(o, parentId)) {

return false;

}

}

return true;

}

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Security实现HTTP认证
下一篇:Java为实体类动态添加属性的方法详解(java给实体类属性默认值)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~