Using the BeanUtils class to copy the same name property between DToS

In the development, we often encounter such a scenario that all fields are queried from the database, but some fields do not want to be given

When the client sees this, it needs to copy the properties from DAO to the DTO object passed to the client. If get/set is used,

That seems like trouble. This can be done using reflection.

 

The Spring framework's org.springframework.beans.BeanUtils class helps us realize this function.

Example
@Data
class Source{

    private String  name;
    private int     age;

    public Source(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

@Data
class Source1{

    private String  home;
    private boolean  flag;

    public Source1(String home, boolean flag) {
        this.home = home;
        this.flag = flag;
    }
}

@Data
class Target{
    private String  name;
    private int     age;
    private String  home;
    private boolean  flag;

}
test
@Slf4j
public class UserInfoDto {

    public static void main(String args[]){
        Source source = new Source("libai",34);
        Source1 source1 = new Source1("nanning",true);
        Target target = new Target();
        BeanUtils.copyProperties(source,target);
        BeanUtils.copyProperties(source1,target);


        log.debug("target = {}",target);
    }
}
output
15:19:33.992 [main] DEBUG com.cloud.microblog.gateway.dto.UserInfoDto - target = Target(name=libai, age=34, home=nanning, flag=true)

Note that the getter/setter method of each Bean class must be implemented.

 

Implementation source code
private static void copyProperties(Object source, Object target, @Nullable Class<?> editable, @Nullable String... ignoreProperties) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();
        if (editable != null) {
            if (!editable.isInstance(target)) {
                throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]");
            }

            actualEditable = editable;
        }

        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
        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 && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                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);
                            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);
                        }
                    }
                }
            }
        }

    }

 

 


Tags: Java Database Spring

Posted on Wed, 04 Dec 2019 01:25:57 -0500 by mikebyrne