PropertyUtil

    将 fromObj 中的全部或者一组属性的值,复制到 toObj 对象中.

    注意点:

    • 如果 toObj 是null,抛出
    • 如果 fromObj 是null,抛出 NullPointerException
    • 对于Date类型,不需要先注册converter
    • 这种copy都是 浅拷贝,复制后的2个Bean的同一个属性可能拥有同一个对象的ref,这个在使用时要小心,特别是对于属性为自定义类的情况 .使用示例:

    返回:

    1. {
    2. "date": "2015-09-06 13:27:43",
    3. "id": 0,
    4. "nickName": [
    5. "feilong",
    6. "飞天奔月",
    7. "venusdrogon"
    8. ],
    9. "age": 0,
    10. "name": "feilong",
    11. "money": 500000,
    12. "userInfo": {"age": 0}
    13. }

    重构:对于以下代码:

    1. private ContactCommand toContactCommand(ShippingInfoSubForm shippingInfoSubForm){
    2. ContactCommand contactCommand = new ContactCommand();
    3. contactCommand.setCountryId(shippingInfoSubForm.getCountryId());
    4. contactCommand.setProvinceId(shippingInfoSubForm.getProvinceId());
    5. contactCommand.setCityId(shippingInfoSubForm.getCityId());
    6. contactCommand.setAreaId(shippingInfoSubForm.getAreaId());
    7. contactCommand.setTownId(shippingInfoSubForm.getTownId());
    8. }

    可以重构成:

    1. private ContactCommand toContactCommand(ShippingInfoSubForm shippingInfoSubForm){
    2. ContactCommand contactCommand = new ContactCommand();
    3. PropertyUtil.copyProperties(contactCommand, shippingInfoSubForm, "countryId", "provinceId", "cityId", "areaId", "townId");
    4. return contactCommand;
    5. }

    可以看出,代码更精简,目的性更明确

    BeanUtils.copyProperties(Object, Object)与 PropertyUtils.copyProperties(Object, Object)区别

    • BeanUtils 提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而 PropertyUtils不支持这个功能,但是速度会更快一些.
    • commons-beanutils v1.9.0以前的版本 BeanUtils不允许对象的属性值为 null,可以拷贝属性值 null的对象.
    • (注:commons-beanutils v1.9.0+修复了这个情况,BeanUtilsBean.copyProperties() no longer throws a ConversionException for null properties of certain data types),具体参阅commons-beanutils的 RELEASE-NOTES.txt相比较直接调用 PropertyUtils.copyProperties(Object, Object)的优点:

    • checkedException 异常转成了 BeanOperationException RuntimeException,因为通常copy的时候出现了checkedException,也是普普通通记录下log,没有更好的处理方式

    • 支持 includePropertyNames 参数,允许针对性copy 个别属性
    • 更多,更容易理解的的javadoc

    返回一个 bean中指定属性 propertyNames可读属性,并将属性名/属性值放入一个 LinkedHashMap 中.

    返回:

    1. {
    2. "id": 5,
    3. "name": "feilong",
    4. "age": null,
    5. "date": "2016-07-13 22:18:26"
    6. }

    场景: 提取user bean "date"和 "id"属性:

    1. User user = new User();
    2. user.setId(5L);
    3. user.setDate(new Date());
    4. LOGGER.debug(JsonUtil.format(PropertyUtil.describe(user, "date", "id"));

    返回的结果,按照指定参数名称顺序:

    1. {
    2. "date": "2016-07-13 22:21:24",
    3. "id": 5
    4. }

    说明:

    • 另外还有一个名为class的属性,属性值是Object的类名,事实上class是java.lang.Object的一个属性
    • 如果 propertyNames是null或者 empty,那么获取所有属性的值
    • map的key按照 propertyNames 的顺序原理:

    • 取到bean class的 java.beans.PropertyDescriptor数组

    • 循环,找到 java.beans.PropertyDescriptor.getReadMethod()

    从指定的 obj中,查找指定类型 toBeFindedClassType 的值.

    说明:

    • 如果 直接返回 findValue
    • 不支持obj是isPrimitiveOrWrapper,CharSequence,Collection,Map类型,自动过滤
    • 调用 PropertyUtil.describe(Object, String) 再递归查找
    • 目前暂不支持从集合里面找到指定类型的值,如果你有相关需求,可以调用 "org.springframework.util.CollectionUtils#findValueOfType(Collection, Class)"示例:**场景:** 从User中找到UserInfo类型的值

    返回:

    1. {"age": 28}

    使用 PropertyUtils.getProperty(Object, String) 从指定bean对象中取得指定属性名称的值.

    • 不会进行类型转换.示例:

    场景: 取list中第一个元素的id

    1. User user = new User();
    2. user.setId(5L);
    3. user.setDate(new Date());
    4. List<User> list = toList(user, user, user);
    5. Long id = PropertyUtil.getProperty(list, "[0].id");

    返回:

    1. 5

    使用 PropertyUtils.setProperty(Object, String, Object) 来设置指定bean对象中的指定属性的值.

    说明:

    • 不会进行类型转换示例:

    返回:

    1. {
    2. "age": 0,
    3. "name": "feilong"
    4. }

    注意点:

    • 如果 bean 是null,抛出 NullPointerException
    • 如果 propertyName 是null,抛出 NullPointerException
    • 如果 propertyName 是blank,抛出 IllegalArgumentException
    • 如果bean没有传入的 propertyName属性名字,会抛出异常,see setSimpleProperty Line2078,转成 BeanOperationException
    • 对于Date类型,不需要先注册converter

    如果 null != value,那么才调用 setProperty(Object, String, Object).

    注意点:

    • 如果 bean 是null,抛出 NullPointerException
    • 如果 propertyName 是null,抛出 NullPointerException
    • 如果 propertyName 是blank,抛出 IllegalArgumentException
    • 如果bean没有传入的 propertyName属性名字,会抛出异常,see PropertyUtilsBean.setSimpleProperty(Object, String, Object) Line2078
    • 对于Date类型,不需要先注册converter

    如果 value isNotNullOrEmpty,那么才调用 setProperty(Object, String, Object).

    注意点:

    • 如果 bean 是null,抛出 NullPointerException
    • 如果 propertyName 是null,抛出 NullPointerException
    • 如果 propertyName 是blank,抛出 IllegalArgumentException
    • 对于Date类型,不需要先注册converter