[置顶] java对象拷贝

package com.unicom.ucloud.eom.common.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 复制对象属性,并支持扩展类型转换
 *
 * @author 闫帆
 */
public class BeanUtils {
    private static Map<String, Method> methodMap = new HashMap<String, Method>();

    static {
        Method methods[] = BeanUtils.class.getMethods();
        for (Method method : methods) {
            methodMap.put(method.getName(), method);
        }
    }


    /**
     * 类似BeanUtisl.copyProperties复制对象
     * 不同之处可以对同名但不同类型的属性赋值
     * 可以配置类型转换方法
     * eg:String赋值给Date 需要编写StringToDate方法
     *
     * @param target 目标对象
     * @param source 源对象
     * @throws Exception
     */
    public static void copyProperties(Object source, Object target) {
        copyProperties(source, target, true);
    }

    /**
     * 类似BeanUtisl.copyProperties复制对象
     * 不同之处可以对同名但不同类型的属性赋值
     * 可以配置类型转换方法
     * eg:String赋值给Date 需要编写StringToDate方法
     *
     * @param target       目标对象
     * @param source       源对象
     * @param nullBeCopied 字段为null的是否复制
     * @throws Exception
     */
    public static void copyProperties(Object source, Object target, Boolean nullBeCopied) {
        copyProperties(source, target, null, null, nullBeCopied);
    }

    /**
     * 指定目标对象中需要复制的属性
     * 支持属性间类型转换 配置类型转换方法 eg:String赋值给Date 需要编写StringToDate方法
     *
     * @param target              目标对象
     * @param source              源对象
     * @param effectiveProperties 需要复制的属性列表
     * @throws Exception
     */
    public static void copyProperties(Object source, Object target, String[] effectiveProperties) {
        copyProperties(source, target, effectiveProperties, null, true);
    }

    /**
     * 指定目标对象需要复制的有效属性和无效属性
     * 支持属性间类型转换 配置类型转换方法 eg:String赋值给Date 需要编写StringToDate方法
     *
     * @param target              目标对象
     * @param source              源对象
     * @param effectiveProperties 需要复制的属性列表
     * @param ignoreProperties    不需要复制的属性列表
     * @param nullBeCopied        字段为null是否复制
     * @throws Exception
     */
    public static void copyProperties(Object source, Object target, String[] effectiveProperties, String[] ignoreProperties, Boolean nullBeCopied) {
        //Field targetFields[]  = destCls.getDeclaredFields();
//		得到自省对象
        BeanInfo beanInfo = null;
        try {
            beanInfo = Introspector.getBeanInfo(source.getClass());
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        //得到key为属性名,value为属性对应的PropertyDescriptor的HashMap
        PropertyDescriptor sourcePds[] = beanInfo.getPropertyDescriptors();
        Map<String, PropertyDescriptor> sourcePdMap = new HashMap<String, PropertyDescriptor>();
        for (PropertyDescriptor sourcePd : sourcePds) {
            sourcePdMap.put(sourcePd.getName(), sourcePd);
        }


        List<String> effectiveList = (null == effectiveProperties) ? null : Arrays.asList(effectiveProperties);
        List<String> ignoreList = (null == ignoreProperties) ? null : Arrays.asList(ignoreProperties);
        try {
            PropertyDescriptor targetPds[] = Introspector.getBeanInfo(target.getClass()).getPropertyDescriptors();
            //遍历目标对象的所有属性
            for (PropertyDescriptor targetPd : targetPds) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(sourcePdMap, targetPd.getName());
                if (null != targetPd.getWriteMethod() && null != sourcePd
                        && (null == effectiveList || effectiveList.contains(targetPd.getName()))
                        && (null == ignoreList || !ignoreList.contains(targetPd.getName()))
                        ) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (null == readMethod) {
                        continue;
                    }
                    Object value = readMethod.invoke(source, null);
                    //当需要验证并且源对象字段为空时跳过
                    if (nullBeCopied == false && null == value) {
                        continue;
                    }
                    Method writeMethod = targetPd.getWriteMethod();
                    //如果目标对象和源对象类型相同时直接赋值
                    if (sourcePd.getPropertyType().isAssignableFrom(targetPd.getPropertyType())) {
                        writeMethod.invoke(target, value);
                    } else { //如果目标对象和源对象类型相不同时,调用类型转换方法
                        String converMethod = getMethodRuleName(sourcePd.getPropertyType().getName(), targetPd.getPropertyType().getName());
                        if (hasConvertMethod(converMethod)) {
                            //调用已注册的类型转换方法
                            value = getConvertMethod(converMethod).invoke(new BeanUtils(), new Object[]{value});
                            writeMethod.invoke(target, value);
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.err.println("复制对象错误");
            e.printStackTrace();
        }
    }


    private static String getMethodRuleName(String sourceTypeName, String targetTypeName) {
        return sourceTypeName.substring(sourceTypeName.lastIndexOf(".") + 1, sourceTypeName.length()) + "To" + targetTypeName.substring(targetTypeName.lastIndexOf(".") + 1, targetTypeName.length());
    }

    private static boolean hasConvertMethod(String methodName) {

        return methodMap.containsKey(methodName);
    }


    private static Method getConvertMethod(String methodName) {
        return methodMap.get(methodName);
    }


    private static PropertyDescriptor getPropertyDescriptor(Map<String, PropertyDescriptor> pdMap, String propertyName) {
        if (pdMap.containsKey(propertyName)) {
            return pdMap.get(propertyName);
        }
        return null;
    }

    /**
     * 将所有空字符串的属性设为null
     *
     * @param object
     */
    public static void setEntryToNull(Object object) {
        BeanInfo beanInfo = null;
        try {
            beanInfo = Introspector.getBeanInfo(object.getClass());
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        PropertyDescriptor objectPds[] = beanInfo.getPropertyDescriptors();
        Object nullObj[] = new Object[1];
        nullObj[0] = null;
        for (PropertyDescriptor objectPd : objectPds) {
            if (objectPd.getPropertyType().isAssignableFrom(String.class) && null != objectPd.getWriteMethod()) {
                try {
                    String value = (String) objectPd.getReadMethod().invoke(object, null);
                    if ("".equals(value)) {
                        objectPd.getWriteMethod().invoke(object, nullObj);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    public static String IntegerToString(Object obj)
    {
    	return String.valueOf(obj);
    }
    
    public static String TimestampToString(Timestamp time)
    {
    	DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	return format.format(time);
    }

//
//	public static Date StringToDate(String obj) {
//		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		if(StringUtils.isEmpty(obj)){
//			return null;
//		}
//		try {
//			return format.parse(obj);
//		} catch (ParseException e) {
//
//			System.err.println(obj+"转换格式错误!");
//			e.printStackTrace();
//			return null;
//		}
//	}

    public static String DateToString(Object obj) {
        return obj.toString();
    }

    public static Date StringToTimestamp(String obj) {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return Timestamp.valueOf(obj);
    }

    /**
     * 返回某类的所有方法集合
     * key = 大写的方法名
     * vale = 方法
     *
     * @param aClass class对象
     */
    public static Map<String, Method> getMethodMap(Class aClass) {
        Map methodMap = new HashMap();
        Method[] methods = aClass.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            methodMap.put(methods[i].getName(), methods[i]);
        }
        return methodMap;
    }

}


posted @ 2013-03-14 11:48  程序员闫帆  阅读(244)  评论(0编辑  收藏  举报