org.springframework.beans.BeanUtils 拷贝对象忽略null值(只拷贝非null属性)

  • 问题描述

开发在中进程经常需要将一个对象的若干个值赋值给另外一个对象相对应的字段,且字段名是一样的,如果一个一个取一个一个赋值太麻烦。有很多类似与org.springframework.beans.BeanUtils的工具类,提供了copyProperties方法,但通过测试发现他会将拷贝对象中的null也拷贝过去,在做一些对象数据更新的操作,我们往往只更新需要更新的值,这时我们就不想拷贝对象中null也被拷贝到目标对象中。

  • 解决办法

通过对org.springframework.beans.BeanUtils的copyProperties源码观察,我们稍作修改就能够达到上述的目的,在拷贝前多加一句判断,下面是封装的工具类

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Modifier;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

/**
 * BeanUtils 可以实现copyProperties 拷贝对象的 null 不复制。
 * @author Fate
 * @version 1.0
 * @date 2020/7/15 22:52
 */
public class MyBeanUtils extends BeanUtils {

    public static void copyProperties(Object source, Object target) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();

        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        PropertyDescriptor[] var7 = targetPds;
        int var8 = targetPds.length;

        for (int var9 = 0; var9 < var8; ++var9) {
            PropertyDescriptor targetPd = var7[var9];
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                        try {
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                readMethod.setAccessible(true);
                            }
                            Object value = readMethod.invoke(source);
                            // 判断value是否为空
                            if (value != null) {
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                    writeMethod.setAccessible(true);
                                }
                                writeMethod.invoke(target, value);
                            }
                        } catch (Throwable var15) {
                            throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var15);
                        }
                    }
                }
            }
        }
    }
}
  • 总结

    经过测试能实现问题描述的目的,但应该有更好的解决办法,有待改进....
原文地址:https://www.cnblogs.com/fate-pc/p/13308800.html