• 一个Bean属性拷贝的工具类


    package com.fpi.spring.qaepb.cps.util;
    
    import java.beans.IntrospectionException;
    import java.beans.PropertyDescriptor;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    import com.fpi.spring.qaepb.cps.entity.po.Project;
    import com.fpi.spring.qaepb.cps.entity.po.ProjectApproval;
    
    /**
     * bean的属性拷贝工具类
     * 
     * @date 2013-12-17
     * 
     * @author yang_qiao
     * 
     * @version 1.0
     */
    public class BeanUtils {
    
        private static final Log logger = LogFactory.getLog(BeanUtils.class);
    
        /** bean嵌套 */
        private static final String NESTED = ".";
    
        /**
         * 复制bean的属性(支持嵌套属性,以点号分割)
         * 
         * @param source
         *            拷贝属性的源对象
         * 
         * @param dest
         *            拷贝属性的目的地对象
         * 
         * @param includeProperties
         *            拷贝的属性列表
         * 
         * @author yang_qiao
         * 
         * @throws InvocationTargetException
         * 
         * @throws IllegalAccessException
         * 
         * @throws IllegalArgumentException
         * 
         * @throws InstantiationException
         * 
         * @throws IntrospectionException
         * 
         * @date 2013-12-18
         */
        public static final void copyIncludeProperties(final Object source,
                Object dest, final String[] includeProperties)
                throws IllegalArgumentException, IllegalAccessException,
                InvocationTargetException, InstantiationException,
                IntrospectionException {
            if (includeProperties == null || includeProperties.length == 0) {
                throw new IllegalArgumentException("未传入要拷贝的属性列表");
            }
            if (source == null) {
                throw new IllegalArgumentException("要拷贝的源对象为空");
            }
            if (dest == null) {
                throw new IllegalArgumentException("要拷贝的目的对象为空");
            }
            // 日志信息
            if (logger.isTraceEnabled()) {
                logger.trace("[source bean: " + source.getClass().getName() + " ]");
                logger.trace("[destination bean: " + dest.getClass().getName()
                        + " ]");
            }
            // 拷贝
            for (String property : includeProperties) {
                PropertyDescriptor sourcePropertyDescriptor = null;
                PropertyDescriptor destPropertyDescriptor = null;
                if (isSimpleProperty(property)) { // 简单属性
                    sourcePropertyDescriptor = getProperty(property, source);
                    destPropertyDescriptor = getProperty(property, dest);
                    if (sourcePropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                    }
                    if (destPropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                    }
                    copyProperty(property, source, dest);
                } else { // 嵌套bean属性
                    Object target = dest;
                    Object realSource = source;
                    String[] nestedProperty = getNestedProperty(property);
                    if (nestedProperty != null && nestedProperty.length > 1) {
                        for (int i = 0; i < nestedProperty.length - 1; i++) {
                            sourcePropertyDescriptor = getProperty(
                                    nestedProperty[i], realSource);
                            destPropertyDescriptor = getProperty(nestedProperty[i],
                                    target);
                            if (sourcePropertyDescriptor == null) {
                                throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                            }
                            if (destPropertyDescriptor == null) {
                                throw new IllegalArgumentException(
                                        "要拷贝到的目标对象不存在该属性");
                            }
                            Method readMethod = sourcePropertyDescriptor
                                    .getReadMethod();
                            realSource = readMethod.invoke(realSource);
                            readMethod = destPropertyDescriptor.getReadMethod();
                            Method writeMethod = destPropertyDescriptor
                                    .getWriteMethod();
                            Object value = readMethod.invoke(target);
                            if (value == null) {
                                value = destPropertyDescriptor.getPropertyType()
                                        .newInstance();
                                writeMethod.invoke(target, value);
                            }
                            target = value;
                        }
                        final String prop = nestedProperty[nestedProperty.length - 1];
                        sourcePropertyDescriptor = getProperty(prop, realSource);
                        destPropertyDescriptor = getProperty(prop, target);
                        if (sourcePropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                        }
                        if (destPropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                        }
                        copyProperty(prop, realSource, target);
                    }
                }
            }
        }
    
        /**
         * 复制bean的属性(支持嵌套属性,以点号分割)
         * 
         * @param source
         *            拷贝属性的源对象
         * 
         * @param dest
         *            拷贝属性的目的地对象
         * 
         * @param includeProperties
         *            拷贝的属性列表
         * 
         * @author yang_qiao
         * 
         * @throws IntrospectionException
         * 
         * @throws InvocationTargetException
         * 
         * @throws IllegalAccessException
         * 
         * @throws IllegalArgumentException
         * 
         * @throws InstantiationException
         * 
         * @throws ClassNotFoundException
         * 
         * @throws IOException
         * 
         * @date 2013-12-18
         */
        public static void copyProperties(final Object source, final Object dest,
                final String... excludeProperties) throws IntrospectionException,
                IllegalArgumentException, IllegalAccessException,
                InvocationTargetException, InstantiationException, IOException,
                ClassNotFoundException {
            final Object backupSource = clone(dest);
            if (source == null) {
                throw new IllegalArgumentException("要拷贝的源对象为空");
            }
            if (dest == null) {
                throw new IllegalArgumentException("要拷贝的目的对象为空");
            }
            org.apache.commons.beanutils.BeanUtils.copyProperties(dest, source);
            // 还原排除的属性值
            revertProperties(backupSource, dest, excludeProperties);
        }
    
        /**
         * 从备份对象中还原属性
         * 
         * @param backup
         *            备份bean
         * 
         * @param target
         *            目标bean
         * 
         * @param properties
         *            属性列表
         * 
         * @author yang_qiao
         * 
         * @throws InvocationTargetException
         * 
         * @throws IllegalAccessException
         * 
         * @throws IllegalArgumentException
         * 
         * @throws IntrospectionException
         * 
         * @throws InstantiationException
         * 
         * @date 2013-12-18
         */
        private static void revertProperties(final Object backup, Object target,
                final String... properties) throws IllegalArgumentException,
                IllegalAccessException, InvocationTargetException,
                IntrospectionException, InstantiationException {
            if (properties == null || properties.length == 0) {
                return;
            }
            if (backup == null) {
                throw new IllegalArgumentException("备份对象为空");
            }
            if (target == null) {
                throw new IllegalArgumentException("目的对象为空");
            }
            // 日志信息
            if (logger.isTraceEnabled()) {
                logger.trace("[source bean: " + backup.getClass().getName() + " ]");
                logger.trace("[destination bean: " + target.getClass().getName()
                        + " ]");
            }
            // 拷贝
            for (String property : properties) {
                PropertyDescriptor sourcePropertyDescriptor = null;
                PropertyDescriptor destPropertyDescriptor = null;
                if (isSimpleProperty(property)) { // 简单属性
                    sourcePropertyDescriptor = getProperty(property, backup);
                    destPropertyDescriptor = getProperty(property, target);
                    if (sourcePropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                    }
                    if (destPropertyDescriptor == null) {
                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                    }
                    copyProperty(property, backup, target);
                } else { // 嵌套bean属性
                    Object targetObj = target;
                    Object realBackup = backup;
                    String[] nestedProperty = getNestedProperty(property);
                    if (nestedProperty != null && nestedProperty.length > 1) {
                        for (int i = 0; i < nestedProperty.length - 1; i++) {
                            sourcePropertyDescriptor = getProperty(
                                    nestedProperty[i], realBackup);
                            destPropertyDescriptor = getProperty(nestedProperty[i],
                                    targetObj);
                            if (sourcePropertyDescriptor == null) {
                                throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                            }
                            if (destPropertyDescriptor == null) {
                                throw new IllegalArgumentException(
                                        "要拷贝到的目标对象不存在该属性");
                            }
                            Method readMethod = sourcePropertyDescriptor
                                    .getReadMethod();
                            realBackup = readMethod.invoke(realBackup);
                            if (realBackup == null) { // 判断备份对象嵌套属性是否为空
                                realBackup = sourcePropertyDescriptor
                                        .getPropertyType().newInstance();
                            }
                            Method writeMethod = destPropertyDescriptor
                                    .getWriteMethod();
                            readMethod = destPropertyDescriptor.getReadMethod();
                            Object value = readMethod.invoke(targetObj);
                            if (value == null) {
                                value = destPropertyDescriptor.getPropertyType()
                                        .newInstance();
                                writeMethod.invoke(targetObj, value);
                            }
                            targetObj = value;
                        }
                        final String prop = nestedProperty[nestedProperty.length - 1];
                        sourcePropertyDescriptor = getProperty(prop, realBackup);
                        destPropertyDescriptor = getProperty(prop, targetObj);
                        if (sourcePropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");
                        }
                        if (destPropertyDescriptor == null) {
                            throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");
                        }
                        copyProperty(prop, realBackup, targetObj);
                    }
                }
            }
        }
    
        /**
         * 对象克隆
         * 
         * @author yang_qiao
         * 
         * @date 2013-12-18
         */
        private static Object clone(final Object value) throws IOException,
                ClassNotFoundException {
            // 字节数组输出流,暂存到内存中
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // 序列化
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(value);
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            // 反序列化
            return ois.readObject();
        }
    
        /**
         * 判断是否为简单属性,是,返回ture
         * 
         * @author yang_qiao
         * 
         * @date 2013-12-18
         */
        private static boolean isSimpleProperty(final String property) {
            return !property.contains(NESTED);
        }
    
        /**
         * 获取目标bean的属性
         * 
         * @author yang_qiao
         * 
         * @date 2013-12-17
         */
        private static PropertyDescriptor getProperty(final String propertyName,
                final Object target) {
            if (target == null) {
                new IllegalArgumentException("查询属性的对象为空");
            }
            if (propertyName == null || "".equals(propertyName)) {
                new IllegalArgumentException("查询属性不能为空值");
            }
            PropertyDescriptor propertyDescriptor = null;
            try {
                propertyDescriptor = new PropertyDescriptor(propertyName,
                        target.getClass());
            } catch (IntrospectionException e) {
                logger.info("不存在该属性");
                return null;
            }
            return propertyDescriptor;
        }
    
        /**
         * 单个属性复制--原数据源和目的数据源必须要有该属性方可
         * 
         * @author yang_qiao
         * 
         * @throws InvocationTargetException
         * 
         * @throws IllegalAccessException
         * 
         * @throws IllegalArgumentException
         * 
         * @throws IntrospectionException
         * 
         * @date 2013-12-17
         */
        public static void copyProperty(final String propertyName,
                final Object source, Object dest) throws IllegalArgumentException,
                IllegalAccessException, InvocationTargetException,
                IntrospectionException {
            PropertyDescriptor property;
            property = new PropertyDescriptor(propertyName, source.getClass());
            Method getMethod = property.getReadMethod();
            Object value = getMethod.invoke(source);
            property = new PropertyDescriptor(propertyName, dest.getClass());
            Method setMethod = property.getWriteMethod();
            setMethod.invoke(dest, value);
        }
    
        /**
         * 获取嵌套Bean的属性
         * 
         * @author yang_qiao
         * 
         * @date 2013-12-18
         */
        public static String[] getNestedProperty(final String nestedProperty) {
            if (nestedProperty == null || "".equals(nestedProperty)) {
                new IllegalArgumentException("参数为空值");
            }
            return nestedProperty.split("\" + NESTED);
        }
    
        public static void main(String[] args) throws IllegalArgumentException,
                IllegalAccessException, InvocationTargetException,
                InstantiationException, IntrospectionException, IOException,
                ClassNotFoundException {
            Project oldProject = new Project();
            Project newProject = new Project();
            ProjectApproval projectApproval = new ProjectApproval();
            projectApproval.setFirstCheckComment("jsoncheck");
            projectApproval.setExplorationComment("shitCheck");
            oldProject.setProjectApproval(projectApproval);
            oldProject.setBuildAddress("json");
            oldProject.setContact("json");
            final String[] includeProperties = new String[] { "contact",
                    "projectApproval.firstCheckComment",
                    "projectApproval.explorationComment" };
            BeanUtils.copyIncludeProperties(oldProject, newProject,
                    includeProperties);
            System.out.println(newProject.getContact());
            System.out.println(newProject.getProjectApproval()
                    .getFirstCheckComment());
            System.out.println(newProject.getProjectApproval()
                    .getExplorationComment());
            System.out.println(newProject.getApprovalStatus());
            System.out.println(newProject.getBuildAddress());
    
            System.out.println("================================");
    
            oldProject = new Project();
            newProject = new Project();
            projectApproval = new ProjectApproval();
            projectApproval.setFirstCheckComment("jsoncheck_");
            projectApproval.setExplorationComment("shitCheck_");
            oldProject.setProjectApproval(projectApproval);
            oldProject.setBuildAddress("json_");
            oldProject.setContact("json_");
            final String[] excludeProperties = null;
            BeanUtils.copyProperties(oldProject, newProject, excludeProperties);
            System.out.println(newProject.getContact());
            System.out.println(newProject.getProjectApproval()
                    .getExplorationComment());
            System.out.println(newProject.getProjectApproval()
                    .getFirstCheckComment());
            System.out.println(newProject.getApprovalStatus());
            System.out.println(newProject.getBuildAddress());
    
        }
    
    }
  • 相关阅读:
    【视频开发】图像清晰度评价方法
    【视频开发】图像清晰度评价方法
    【VS开发】MFC修改Opencv namedWindow的风格
    【VS开发】MFC修改Opencv namedWindow的风格
    【ARM-Linux开发】ctrl-xxx的对应的signal含义
    【ARM-Linux开发】ctrl-xxx的对应的signal含义
    【VS开发】程序如何捕捉signal函数参数中指定的信号
    【VS开发】程序如何捕捉signal函数参数中指定的信号
    【VS开发】windows下的signal
    【VS开发】windows下的signal
  • 原文地址:https://www.cnblogs.com/binger/p/3489558.html
Copyright © 2020-2023  润新知