BeanPath
# 由来
很多JavaBean嵌套着很多层对象,这其中还夹杂着Map、Collection等对象,因此获取太深的嵌套对象会让代码变得冗长不堪。因此我们可以考虑使用一种表达式来获取指定深度的对象,于是BeanPath应运而生。
# 原理
Bean路径表达式,用于获取多层嵌套Bean中的字段值或Bean对象。根据给定的表达式,查找Bean中对应的属性值对象
表达式分为两种:
.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值[]表达式,可以获取集合等对象中对应index的值
栗子:
person获取Bean对象下person字段的值,或者Bean本身如果是Person对象,返回本身。person.name获取Bean中person字段下name字段的值,或者Bean本身如果是Person对象,返回其name字段的值。persons[3]获取persons字段下第三个元素的值(假设person是数组或Collection对象)person.friends[5].name获取person字段下friends列表(或数组)的第5个元素对象的name属性
# 方法
# 常用方法
of创建Bean路径getNode获取节点getChild获取子表达式getValue获取路径对应的值setValue设置路径对应的值,如果路径节点为空,自动创建之invoke执行原始Bean中的方法getBean获得原始BeangetBeanClass获得Bean的类型
# 使用
定义一个Map包含用户信息(UserInfoDict)和一个标志位(flag),用户信息包括一些基本信息和一个考试信息列表(ExamInfoDict)。
public void init() {
Map<String, Object> tempMap;
// ------------------------------------------------- 考试信息列表
final ExamInfoDict examInfoDict = new ExamInfoDict();
examInfoDict.setId(1);
examInfoDict.setExamType(0);
examInfoDict.setAnswerIs(1);
final ExamInfoDict examInfoDict1 = new ExamInfoDict();
examInfoDict1.setId(2);
examInfoDict1.setExamType(0);
examInfoDict1.setAnswerIs(0);
final ExamInfoDict examInfoDict2 = new ExamInfoDict();
examInfoDict2.setId(3);
examInfoDict2.setExamType(1);
examInfoDict2.setAnswerIs(0);
final List<ExamInfoDict> examInfoDicts = new ArrayList<>();
examInfoDicts.add(examInfoDict);
examInfoDicts.add(examInfoDict1);
examInfoDicts.add(examInfoDict2);
// ------------------------------------------------- 用户信息
final UserInfoDict userInfoDict = new UserInfoDict();
userInfoDict.setId(1);
userInfoDict.setPhotoPath("yx.mm.com");
userInfoDict.setRealName("张三");
userInfoDict.setExamInfoDict(examInfoDicts);
tempMap = new HashMap<>();
tempMap.put("userInfo", userInfoDict);
tempMap.put("flag", 1);
}
下面,我们使用BeanPath获取这个Map下此用户第一门考试的ID:
public void getValueTest() {
final BeanPath beanPath = BeanPath.of("$.userInfo.examInfoDict[0].id");
// final BeanPath pattern = new BeanPath("$.userInfo.examInfoDict[0].id");
final Object result = pattern.getValue(tempMap);
Assertions.assertEquals(1, result);
}
只需两句(甚至一句)即可完成复杂Bean中各层次对象的获取。
接下来,我们使用BeanPath设置这个Map下此用户第一门考试的ID:
public void setValueTest() {
final BeanPath beanPath = BeanPath.of("$.userInfo.examInfoDict[0].id");
// final BeanPath pattern = new BeanPath("userInfo.examInfoDict[0].id");
pattern.setValue(tempMap, 2);
final Object result = pattern.getValue(tempMap);
Assertions.assertEquals(2, result);
}