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());
}
}
相关推荐
内容概要:本资源提供了一个Java Bean转换工具类示例,展示了如何使用反射和JSON序列化实现对象之间的属性拷贝。该工具类包含两个主要方法:convertTo和convertByJackson,前者基于反射用于结构相同的对象间的属性...
4. **数据拷贝**:这个工具类可能包含了复制Bean对象到另一个相同类型Bean的功能,这通常用于创建Bean对象的副本,避免对原对象的修改影响到其他地方。可以使用如Apache Commons BeanUtils的`copyProperties(Object ...
在Java编程中,反射(Reflection)是一个强大的工具,它允许我们在运行时检查和操作类、接口、字段和方法。通过反射,我们可以动态地创建对象、访问私有成员、调用私有方法,甚至改变对象的行为。Java反射 API 主要...
2. **集合转换**:如果需要将一个Bean对象列表转换为另一种类型的Bean对象列表,Bean Util工具类提供了便利的方法。这在处理数据模型转换或接口适配时非常有用。 3. **自定义转换**:除了默认的属性类型转换外,还...
BeanUtil 拷贝一个bean中的非空属性于另一个bean中 CopyOfJExcelUtils excel 工具类 DateUtil 时间工具类 FileUtils 文件工具类 JExcelUtils excel 工具类2 JsonUtil json 工具类 MyBeanUtils 实体bean 工具 ...
Cglib BeanCopier是阿里巴巴Fastjson项目中的一个组件,它是基于代码生成技术的,因此在性能上远超前三个框架。Cglib在运行时动态生成子类,重写getter和setter方法,从而避免了反射的性能损耗。但是,Cglib的使用...
Apache BeanUtils是一个强大的Java Bean操作工具包,它简化了对Java对象属性的访问,使得开发者无需直接使用Java反射API即可方便地操作对象属性。在Java开发中,BeanUtils组件是Apache Commons项目的一部分,旨在...
标题中的"common(bean_之音属性复制).zip"提到了一个关于Java Bean属性复制的主题,这通常指的是对象间的属性拷贝或者映射过程。在Java开发中,特别是Spring框架中,Bean的属性复制是一个常见操作,它有助于减少...
然后,我们可以创建一个工具类,该类使用反射来遍历目标对象的所有字段,检查它们是否带有`@CopyField`注解,并根据注解信息从源对象中拷贝对应的值: ```java public class CopyUtil { public static void ...
1. **属性拷贝**:`BeanUtils.copyProperties()`方法可以方便地将一个对象的属性值复制到另一个对象,大大简化了对象间的属性映射。 2. **属性访问**:`PropertyUtils`类提供了对Java对象属性的无反射访问,可以...
在Java编程中,将JSON对象转换为Java Bean对象是一个常见的任务,特别是在处理Web服务或API交互时。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,而Java Bean是符合特定规范的Java类,通常用于...
在Java开发中,Apache Commons BeanUtils库是一个非常实用的工具包,它提供了许多方便的方法来操作JavaBeans。本文将深入探讨`BeanUtilsBean`对象复制的功能,特别关注它如何实现类型自动转换。`BeanUtilsBean`是...
"jodd-bean-3.4.5.zip"是Jodd库的一部分,为Java开发人员提供了强大的Bean操作工具,而"analytics-client.zip"则是一个用于3WKS分析平台的客户端库,帮助开发者集成分析服务到他们的应用中。这两个项目都是开源的,...
BeanUtils工具.jar包是Apache Commons项目中的一个核心组件,它为Java开发人员提供了一套方便的工具类,用于处理Java Bean对象之间的属性复制、类型转换等常见操作。这个库简化了对象模型之间的数据绑定,特别是在...
在Java开发中,BeanUtils工具类是Apache Commons项目的一个重要组成部分,主要负责处理Java Bean对象之间的属性复制,提供了便捷的数据绑定功能。对于那些正在学习如何使用Java连接MySQL的初学者来说,了解并掌握...
`json-lib`是一个Java库,它提供了处理JSON的工具类,使得在Java环境中操作JSON对象变得更加便捷。本文将详细讲解`JsonUtils`工具类在`json-lib`中的使用方法及其相关知识点。 `JsonUtils`是`json-lib`库中的核心...
奥里卡(Orika)是一个Java Bean映射框架,它为开发者提供了在Java对象之间进行自动数据转换的简便方法。这个框架的主要目标是简化对象之间的属性映射过程,减轻开发人员手动编写转换代码的负担。Orika 1.5.4是其一...
- **属性拷贝**:`copyProperties()`方法使得能够将一个Bean的所有属性值复制到另一个Bean,大大简化了对象之间的数据迁移。 - **类型转换**:库内置了自动类型转换机制,当尝试将一个对象赋值给不匹配类型的Bean...
1. **属性拷贝**:通过`copyProperties()`方法,可以将一个Java Bean的所有属性值复制到另一个Bean中,无需手动编写setter和getter方法。这对于数据模型的转换非常有用。 2. **反射操作**:BeanUtils库利用Java的...