BeanPath

Origin

Many JavaBeans contain multiple nested objects, mixed with objects such as Maps and Collections, which can make it difficult to access deeply nested objects. As a result, it may be considered to use an expression to obtain objects of a specified depth. This is where BeanResolver comes into play.

Principle

By passing in an expression, it follows the rules of the expression to retrieve the desired object under the bean.

Expressions are divided into two types:

  1. . expression - used to obtain the value of an attribute (field) within a Bean object or the value corresponding to a key in a Map.
  2. [] expression - used to obtain the value at a specific index within an object such as an array or Collection.

Examples:

  1. person - obtains the value of the person field within the Bean object, or if the Bean itself is a Person object, returns itself.
  2. person.name - obtains the value of the name field within the person field within the Bean, or if the Bean itself is a Person object, returns the value of its name field.
  3. persons[3] - obtains the value of the third element within the persons field (assuming person is an array or Collection object).
  4. person.friends[5].name - obtains the name attribute of the fifth element object within the friends list (or array) within the person field.

Usage

Due to the complexity of nested Bean definitions, we have omitted them here. Interested parties can refer to the test case bean definitions located at cn.hutool.core.lang.test.bean (under src/test/java). We first create this complex Bean (in reality, this complex Bean may be obtained from a database or transferred from JSON).

//------------------------------------------------- Exam Information List

ExamInfoDict examInfoDict = new ExamInfoDict();
examInfoDict.setId(1);
examInfoDict.setExamType(0);
examInfoDict.setAnswerIs(1);

ExamInfoDict examInfoDict1 = new ExamInfoDict();
examInfoDict1.setId(2);
examInfoDict1.setExamType(0);
examInfoDict1.setAnswerIs(0);

ExamInfoDict examInfoDict2 = new ExamInfoDict();
examInfoDict2.setId(3);
examInfoDict2.setExamType(1);
examInfoDict2.setAnswerIs(0);

List<ExamInfoDict> examInfoDicts = new ArrayList<ExamInfoDict>();
examInfoDicts.add(examInfoDict);
examInfoDicts.add(examInfoDict1);
examInfoDicts.add(examInfoDict2);

//------------------------------------------------- User Information

UserInfoDict userInfoDict = new UserInfoDict();
userInfoDict.setId(1);
userInfoDict.setPhotoPath("yx.mm.com");
userInfoDict.setRealName("Zhang San");
userInfoDict.setExamInfoDict(examInfoDicts);

Map<String, Object> tempMap = new HashMap<String, Object>();
tempMap.put("userInfo", userInfoDict);
tempMap.put("flag", 1);
// Below, we use `BeanPath` to obtain the ID of the first exam of this user in the Map:
BeanPath resolver = new BeanPath("userInfo.examInfoDict[0].id");
Object result = resolver.get(tempMap);//ID is 1

Only two sentences (or even one sentence) are needed to complete the retrieval of objects at different levels in complex Beans.

Explanation: To simplify the usage of BeanPath, Hutool also includes a shortcut entry method in BeanUtil: BeanUtil.getProperty. This method is easier to understand as its name is more intuitive (since BeanPath can not only parse Beans but also parse Maps and collections).