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; }}