BeanUtils.copyProperties忽略null方法

这篇博客介绍了如何使用BeanUtils.copyProperties方法,结合自定义的getNullPropertyNames函数,从DTO对象拷贝属性到实体类时忽略空值,保持实体类中默认值。这种方法有助于在数据转换时保持对象状态的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常用于拷贝DTO对象属性到实体类,实体类中部分字段有设置默认值,即可以不将DTO中的空值拷贝过来,保持原有默认值

BeanUtils.copyProperties(source, target, getNullPropertyNames(source));

可以将下面的方法做成一个Util使用, source会忽略null值复制到target中

public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set emptyNames = new HashSet();
        for(java.beans.PropertyDescriptor pd : pds) {
            //check if value of this property is null then add it to the collection
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return (String[]) emptyNames.toArray(result);
    }




<think>好的,我现在需要解决用户的问题:如何在使用BeanUtils.copyProperties忽略null值。用户提到了几个引用,我需要先仔细看看这些引用中的信息,然后整理出一个清晰的步骤。 首先,根据引用[1]和[4],用户提到可以使用BeanUtils.copyProperties(source, target, getNullPropertyNames(source)),其中getNullPropertyNames(source)方法可以获取源对象中为null的属性名,这样在复制时就会忽略这些null值的属性。引用[3]也提到可以通过添加可变长参数来忽略某些字段,包括null值的字段。 接下来,我需要确认这个getNullPropertyNames方法的实现。根据引用[1]和[4],这个方法需要自己编写,用于检测源对象中的null属性。比如,使用反射遍历源对象的属性,找出值为null的字段名,然后返回这些字段名的数组。这样在调用copyProperties时,第三个参数传入这些字段名,就能忽略它们。 然后,引用[3]提到使用三个参数的copyProperties方法,第三个参数是可变长参数,可以传入需要忽略的字段名。比如BeanUtils.copyProperties(newdata, dbdata, "id", "password"),这样id和password字段就不会被覆盖。但用户的需求是自动忽略所有null值的字段,而不是手动指定,所以需要结合getNullPropertyNames方法来自动获取这些字段名。 可能的步骤是: 1. 实现一个工具方法getNullPropertyNames,该方法接收源对象,返回所有值为null的属性名数组。 2. 在调用BeanUtils.copyProperties时,传入源对象、目标对象和这个工具方法返回的数组。 3. 这样,所有源对象中为null的属性就不会被复制到目标对象中,保留目标对象原有的值。 需要注意的是,BeanUtils.copyProperties的具体实现可能因版本或库的不同而有所差异。用户提到的引用中,使用的是Spring的BeanUtils还是Apache Commons的BeanUtils?根据引用[3],用户提到使用的是Spring提供的BeanUtils,而Apache Commons的BeanUtils可能没有相同的参数。因此,在实现时需要确认使用的是Spring的版本,因为Apache Commons的BeanUtils.copyProperties方法可能不支持忽略null值的参数,需要自定义处理。 另外,引用[2]提到在开发中需要过滤null值,忽略拷贝,但具体的实现方法需要结合工具方法。所以,正确的做法应该是使用Spring的BeanUtils,并配合自定义的getNullPropertyNames方法。 现在,需要验证这个方法的正确性。例如,如果源对象中的某个属性为null,那么在调用copyProperties时,该属性不会被复制到目标对象,目标对象对应的属性保持原来的值。如果源对象的属性不为null,则会被复制到目标对象。这应该能解决用户的问题,避免null值覆盖目标对象中的已有值。 总结步骤: - 编写getNullPropertyNames方法,获取源对象中null值的属性名。 - 调用BeanUtils.copyProperties(source, target, getNullPropertyNames(source))。 - 确保使用的是Spring的BeanUtils,而非其他库的版本。 同时,需要注意异常处理,例如源对象或目标对象为null的情况,以及属性访问权限的问题。反射可能需要处理私有字段,确保有适当的访问权限。 最后,根据用户提供的引用,特别是引用[1]、[3]、[4],正确的实现方法已经存在,只需要按照这些步骤编写代码即可。</think>### 如何在使用 BeanUtils.copyProperties忽略 null 值? 在使用 `BeanUtils.copyProperties` 进行对象属性拷贝时,若需要忽略源对象中值为 `null` 的字段,可以通过以下步骤实现: --- #### 1. **使用 Spring 提供的 BeanUtils 工具类** 确保使用的是 **Spring Framework** 的 `BeanUtils.copyProperties` 方法(而非 Apache Commons 的版本),因为 Spring 的该方法支持通过参数指定忽略的字段[^3]。 --- #### 2. **实现获取 null 属性名的方法** 自定义一个工具方法 `getNullPropertyNames`,用于提取源对象中值为 `null` 的属性名列表。该方法基于反射实现: ```java public static String[] getNullPropertyNames(Object source) { BeanWrapper src = new BeanWrapperImpl(source); PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> nullPropertyNames = new HashSet<>(); for (PropertyDescriptor pd : pds) { String propertyName = pd.getName(); Object value = src.getPropertyValue(propertyName); if (value == null) { nullPropertyNames.add(propertyName); } } return nullPropertyNames.toArray(new String[0]); } ``` **说明**: - 通过 `BeanWrapper` 遍历源对象的所有属性。 - 若属性值为 `null`,则记录其名称[^1][^4]。 --- #### 3. **调用 copyProperties忽略 null 字段** 在拷贝时,将 `getNullPropertyNames` 的返回值作为第三个参数传入: ```java BeanUtils.copyProperties(source, target, getNullPropertyNames(source)); ``` **效果**: - 仅复制源对象中非 `null` 的属性值到目标对象。 - 目标对象中未被覆盖的字段保留原有值。 --- #### 代码示例 ```java // 假设 UserDTO 是源对象,UserEntity 是目标对象 UserDTO userDTO = new UserDTO(); userDTO.setName("Alice"); userDTO.setAge(null); // age 为 null UserEntity userEntity = new UserEntity(); userEntity.setAge(30); // 目标对象原有 age=30 // 拷贝时忽略 nullBeanUtils.copyProperties(userDTO, userEntity, getNullPropertyNames(userDTO)); // 结果:userEntity 的 name 变为 "Alice",age 仍为 30(未被覆盖) ``` --- ### 注意事项 1. **版本兼容性**: Spring 的 `BeanUtils.copyProperties` 支持可变长参数(需 Spring 5.0+),低版本可能需要调整参数类型。 2. **性能优化**: 反射操作可能影响性能,频繁调用时可考虑缓存属性列表。 3. **字段匹配规则**: 仅当源和目标对象的属性名和类型一致时才会拷贝。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值