`

一个Bean属性拷贝的工具类

    博客分类:
  • java
 
阅读更多

 

复制代码
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());

    }

}
复制代码
分享到:
评论

相关推荐

    BeanConvertor工具类Java开发Bean转换拷贝工具类

    内容概要:本资源提供了一个Java Bean转换工具类示例,展示了如何使用反射和JSON序列化实现对象之间的属性拷贝。该工具类包含两个主要方法:convertTo和convertByJackson,前者基于反射用于结构相同的对象间的属性...

    bean,json工具类

    4. **数据拷贝**:这个工具类可能包含了复制Bean对象到另一个相同类型Bean的功能,这通常用于创建Bean对象的副本,避免对原对象的修改影响到其他地方。可以使用如Apache Commons BeanUtils的`copyProperties(Object ...

    java反射以及复制一个bean的值到另一个bean中。

    在Java编程中,反射(Reflection)是一个强大的工具,它允许我们在运行时检查和操作类、接口、字段和方法。通过反射,我们可以动态地创建对象、访问私有成员、调用私有方法,甚至改变对象的行为。Java反射 API 主要...

    bean_util_test.zip

    2. **集合转换**:如果需要将一个Bean对象列表转换为另一种类型的Bean对象列表,Bean Util工具类提供了便利的方法。这在处理数据模型转换或接口适配时非常有用。 3. **自定义转换**:除了默认的属性类型转换外,还...

    web 项目中的各种工具类

    BeanUtil 拷贝一个bean中的非空属性于另一个bean中 CopyOfJExcelUtils excel 工具类 DateUtil 时间工具类 FileUtils 文件工具类 JExcelUtils excel 工具类2 JsonUtil json 工具类 MyBeanUtils 实体bean 工具 ...

    Bean复制的几种框架性能比较(Apache BeanUtils、PropertyUtils,Spring BeanUtils,Cglib BeanCopier

    Cglib BeanCopier是阿里巴巴Fastjson项目中的一个组件,它是基于代码生成技术的,因此在性能上远超前三个框架。Cglib在运行时动态生成子类,重写getter和setter方法,从而避免了反射的性能损耗。但是,Cglib的使用...

    封装对象工具类jar包.zip

    Apache BeanUtils是一个强大的Java Bean操作工具包,它简化了对Java对象属性的访问,使得开发者无需直接使用Java反射API即可方便地操作对象属性。在Java开发中,BeanUtils组件是Apache Commons项目的一部分,旨在...

    common(bean_之音属性复制).zip

    标题中的"common(bean_之音属性复制).zip"提到了一个关于Java Bean属性复制的主题,这通常指的是对象间的属性拷贝或者映射过程。在Java开发中,特别是Spring框架中,Bean的属性复制是一个常见操作,它有助于减少...

    利用annotation完成对象间的属性拷贝

    然后,我们可以创建一个工具类,该类使用反射来遍历目标对象的所有字段,检查它们是否带有`@CopyField`注解,并根据注解信息从源对象中拷贝对应的值: ```java public class CopyUtil { public static void ...

    Java工具类之Apache的Commons Lang和BeanUtils

    1. **属性拷贝**:`BeanUtils.copyProperties()`方法可以方便地将一个对象的属性值复制到另一个对象,大大简化了对象间的属性映射。 2. **属性访问**:`PropertyUtils`类提供了对Java对象属性的无反射访问,可以...

    拷贝JSON对象值进Java Bean对象

    在Java编程中,将JSON对象转换为Java Bean对象是一个常见的任务,特别是在处理Web服务或API交互时。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,而Java Bean是符合特定规范的Java类,通常用于...

    BeanUtilsBean对象复制使用(类型可以自动转化)

    在Java开发中,Apache Commons BeanUtils库是一个非常实用的工具包,它提供了许多方便的方法来操作JavaBeans。本文将深入探讨`BeanUtilsBean`对象复制的功能,特别关注它如何实现类型自动转换。`BeanUtilsBean`是...

    jodd-bean-3.4.5.zip

    "jodd-bean-3.4.5.zip"是Jodd库的一部分,为Java开发人员提供了强大的Bean操作工具,而"analytics-client.zip"则是一个用于3WKS分析平台的客户端库,帮助开发者集成分析服务到他们的应用中。这两个项目都是开源的,...

    BeanUtils工具 .jar 包

    BeanUtils工具.jar包是Apache Commons项目中的一个核心组件,它为Java开发人员提供了一套方便的工具类,用于处理Java Bean对象之间的属性复制、类型转换等常见操作。这个库简化了对象模型之间的数据绑定,特别是在...

    BeanUtils工具类

    在Java开发中,BeanUtils工具类是Apache Commons项目的一个重要组成部分,主要负责处理Java Bean对象之间的属性复制,提供了便捷的数据绑定功能。对于那些正在学习如何使用Java连接MySQL的初学者来说,了解并掌握...

    json-lib JsonUtils 工具类,json-lib 工具类

    `json-lib`是一个Java库,它提供了处理JSON的工具类,使得在Java环境中操作JSON对象变得更加便捷。本文将详细讲解`JsonUtils`工具类在`json-lib`中的使用方法及其相关知识点。 `JsonUtils`是`json-lib`库中的核心...

    orika,更简单、更好和更快的java bean映射框架.zip

    奥里卡(Orika)是一个Java Bean映射框架,它为开发者提供了在Java对象之间进行自动数据转换的简便方法。这个框架的主要目标是简化对象之间的属性映射过程,减轻开发人员手动编写转换代码的负担。Orika 1.5.4是其一...

    commons-beanutils (1.7.0 -1.9.2)6个

    - **属性拷贝**:`copyProperties()`方法使得能够将一个Bean的所有属性值复制到另一个Bean,大大简化了对象之间的数据迁移。 - **类型转换**:库内置了自动类型转换机制,当尝试将一个对象赋值给不匹配类型的Bean...

    Commons BeanUtils 1.8.3 API

    1. **属性拷贝**:通过`copyProperties()`方法,可以将一个Java Bean的所有属性值复制到另一个Bean中,无需手动编写setter和getter方法。这对于数据模型的转换非常有用。 2. **反射操作**:BeanUtils库利用Java的...

Global site tag (gtag.js) - Google Analytics