好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java 类动态添加属性字段的操作

说明:

做项目中遇到一种场景,需要根据查询时间段, 获取时间段中中每个月份对应的金额(费用统计)。

如截图中的两列

因为列是动态的, 首先想到的就是后天拼接JSON格式字符串, 然后返回到前台, 组装表头及内容。

但是当前系统中easyUI版本为1.2,并不支持 data属性(官方从1.3.2开始支持)。所以只能返回list<T> 格式。

网上一搜相关代码很多, 看客可以自己搜索一下。 我这里记录一下我当时使用场景及用法,已备以后使用。

1.需要引用cglib jar包, 我用的版本是2.2

2.建一个实体对象 DynamicBean.java 。主要用来处理对象。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

public class DynamicBean {

  private Object object = null ; // 动态生成的类

  private BeanMap beanMap = null ; // 存放属性名称以及属性的类型

  public DynamicBean() {

   super ();

  }

 

  public DynamicBean(Map propertyMap) {

   this .object = generateBean(propertyMap);

   this .beanMap = BeanMap.create( this .object);

  }

 

  /**

   * @param propertyMap

   * @return

   */

  private Object generateBean(Map propertyMap) {

   BeanGenerator generator = new BeanGenerator();

   Set keySet = propertyMap.keySet();

   for (Iterator<String> i = keySet.iterator(); i.hasNext();) {

    String key = (String) i.next();

    generator.addProperty(key, (Class) propertyMap.get(key));

   }

   return generator.create();

  }

 

  /**

   * ??bean??????

   * @param property ??????

   * @param value ?

   */

  public void setValue(Object property, Object value) {

   beanMap.put(property, value);

  }

 

  /**

   * ??????????õ??????

   * @param property ??????

   * @return ?

   */

  public Object getValue(String property) {

   return beanMap.get(property);

  }

 

  /**

   * 返回新生成的对象

   * @return

   */

  public Object getObject() {

   return this .object;

  }

}

3. 原来对象, 及需要拼接到对象中的属性字段集合处理方法。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

/**

*参数说明:

* object : 查询结果数组中对象。

* moneyMap : 为对象对应所有月份数据集合

* 解释:已经查询出一组账单对象集合List<Bill> , 而moneyMap为对象中的一个属性

* Map<String,Bigdecimal>, 存放了月份及金额

*/

private Object dynamicClass(Object object, Map<String, BigDecimal> moneyMap) throws Exception {

   // 字段 - 值 集合

   HashMap<String, Object> returnMap = new HashMap<String, Object>();

   // 字段 - 字段类型 集合

   HashMap<String, Object> typeMap = new HashMap<String, Object>();

   // 获取传入类

   Class<? extends Object> type = object.getClass();

   BeanInfo beanInfo = Introspector.getBeanInfo(type);

   PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

   // 获取对象中已存在的数据

   for ( int i = 0 ; i < propertyDescriptors.length; i++) {

    PropertyDescriptor descriptor = propertyDescriptors[i];

    String propertyName = descriptor.getName();

    if (!propertyName.equals( "class" ) && !propertyName.equals( "monthMap" )) {

     Method readMethod = descriptor.getReadMethod();

     Object result = readMethod.invoke(object, new Object[ 0 ]);

     if (result != null ) {

      returnMap.put(propertyName, result);

     } else {

      String propertyType = descriptor.getPropertyType().toString();

      if (propertyType.contains( "java.math.BigDecimal" )) {

       returnMap.put(propertyName, new BigDecimal( 0 ));

      } else {

       returnMap.put(propertyName, "" );

      }

     }

     typeMap.put(propertyName, descriptor.getPropertyType());

    }

   }

   // 获取月份数据, 变为字段属性

   Set<String> monthKeys = moneyMap.keySet();

   for (Iterator<String> it = monthKeys.iterator(); it.hasNext();) {

    String key = (String) it.next();

    // 字段类型

    typeMap.put(key, Class.forName( "java.math.BigDecimal" ));

    // 字段对应值

    returnMap.put(key, moneyMap.get(key));

   }

   // map转换成实体对象

   DynamicBean bean = new DynamicBean(typeMap);

   // 赋值

   Set<String> keys = typeMap.keySet();

   for (Iterator<String> it = keys.iterator(); it.hasNext();) {

    String key = (String) it.next();

    bean.setValue(key, returnMap.get(key));

   }

   Object obj = bean.getObject();

   return obj;

  }

做笔记使用, 说不定以后还会用到。

补充:java动态的生成类的属性、并赋值

1、springboot项目中,在build.gradle中,配置jar包

?

1

2

compile( "commons-beanutils:commons-beanutils:1.9.3" )

compile( "cglib:cglib-nodep:3.2.4" )

2、创建DynamicBean

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

import java.util.Map;

import net.sf.cglib.beans.BeanGenerator;

import net.sf.cglib.beans.BeanMap;

public class DynamicBean {

 

  /**

   * 目标对象

   */

  private Object target;

  /**

   * 属性集合

   */

  private BeanMap beanMap;

 

  public DynamicBean(Class superclass, Map<String, Class> propertyMap){

   this .target = generateBean(superclass, propertyMap);

   this .beanMap = BeanMap.create( this .target);

  }

 

  /**

   * bean 添加属性和值

   *

   * @param property

   * @param value

   */

  public void setValue(String property, Object value) {

   beanMap.put(property, value);

  }

 

  /**

   * 获取属性值

   *

   * @param property

   * @return

   */

  public Object getValue(String property) {

   return beanMap.get(property);

  }

 

  /**

   * 获取对象

   *

   * @return

   */

  public Object getTarget() {

   return this .target;

  }

 

  /**

   * 根据属性生成对象

   *

   * @param superclass

   * @param propertyMap

   * @return

   */

  private Object generateBean(Class superclass, Map<String, Class> propertyMap) {

   BeanGenerator generator = new BeanGenerator();

   if ( null != superclass) {

    generator.setSuperclass(superclass);

   }

   BeanGenerator.addProperties(generator, propertyMap);

   return generator.create();

  }

}

3、创建ReflecUtil转换的工具类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

import java.beans.PropertyDescriptor;

import java.util.HashMap;

import java.util.Map;

import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.Logger;

import org.apache测试数据mons.beanutils.PropertyUtilsBean;

import com.sunxung.factoring.entity.DynamicBean;

import com.sunxung.factoring.entity.attendanceManagement.AttendanceVo;

 

/**

  * @className:ReflectUtil

  * @description:动态生成类的属性、并且赋值

  * @date:2018年4月3日 下午2:33:10

  */

public class ReflectUtil {

 

  static Logger logger = LogManager.getLogger(ReflectUtil. class );

 

  @SuppressWarnings ( "rawtypes" )

  public static Object getTarget(Object dest, Map<String, Object> addProperties) {

   PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();

   PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(dest);

   Map<String, Class> propertyMap = new HashMap<>();

   for (PropertyDescriptor d : descriptors) {

    if (! "class" .equalsIgnoreCase(d.getName())) {

     propertyMap.put(d.getName(), d.getPropertyType());

    }

   }

   // add extra properties

   addProperties.forEach((k, v) -> propertyMap.put(k, v.getClass()));

   // new dynamic bean

   DynamicBean dynamicBean = new DynamicBean(dest.getClass(), propertyMap);

   // add old value

   propertyMap.forEach((k, v) -> {

    try {

     // filter extra properties

     if (!addProperties.containsKey(k)) {

      dynamicBean.setValue(k, propertyUtilsBean.getNestedProperty(dest, k));

     }

    } catch (Exception e) {

     logger.error(e.getMessage(), e);

    }

   });

   // add extra value

   addProperties.forEach((k, v) -> {

    try {

     dynamicBean.setValue(k, v);

    } catch (Exception e) {

     logger.error(e.getMessage(), e);

    }

   });

   Object target = dynamicBean.getTarget();

   return target;

  }

 

  public static void main(String[] args) {

   AttendanceVo entity = new AttendanceVo();

   Map<String, Object> addProperties = new HashMap<>();

   addProperties.put( "day31" , "你好" );

   AttendanceVo newVo = (AttendanceVo) getTarget(entity, addProperties);

   System.out.println(newVo.getDay0());

  }

}

4、在项目中动态生成属性并且赋值的使用

?

1

2

3

4

5

6

7

8

9

10

11

private AttendanceVo autoDetailNew(SearchAttendanceVo search, AttendanceVo att) {

   search.setDingdingUserId(att.getDingdingUserId());

   List<Attendance> detailList = attendanceMapper.findDetailList(search);

   Map<String, Object> addProperties = new HashMap<>();

   for (Attendance attendance : detailList) {

    addProperties.put( "day" + DateUtil.getDayStringFormatYMD(attendance.getAttendanceDate()),

      attendance.getRemark());

   }

   AttendanceVo newVo = (AttendanceVo) ReflectUtil.getTarget(att, addProperties);

   return newVo;

  }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

原文链接:https://blog.csdn.net/WUWENJINWUWENJIN/article/details/83276553

查看更多关于Java 类动态添加属性字段的操作的详细内容...

  阅读:137次