package com.franson.study.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.avalon.framework.service.ServiceException; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class BeanUtil { private static Log log = LogFactory.getLog(BeanUtil.class); /** * 兩物件之間的拷貝(在目標物件中存在的所有set方法,如果在源物件中存在對應的get方法,不管源物件的get方法的返回值是否為null,都進行拷貝) * 僅拷貝方法名及方法返回型別完全一樣的屬性值 * @param desc 目標物件 * @param orig 源物件 * @param excludeFields 不拷貝的field(多個用逗號隔開) */ public static void copyPropertiesNotForce(Object desc, Object orig,String excludeFields) { copyPropertiesNotForce(desc, orig, excludeFields, true); } /** * 兩物件之間的拷貝(在目標物件中存在的所有set方法,如果在源物件中存在對應的get方法,不管源物件的get方法的返回值是否為null,都進行拷貝) * 僅拷貝方法名及方法返回型別完全一樣的屬性值 * @param desc 目標物件 * @param orig 源物件 * @param excludeFields 源物件 * @param isCopyNull 為null的屬性是否拷貝(true拷貝null屬性;false不拷貝null屬性) * @param excludeFields 不拷貝的field(多個用逗號隔開) */ public static void copyPropertiesNotForce(Object desc, Object orig,String excludeFields, boolean isCopyNull) { Class<?> origClass = orig.getClass(); Class<?> descClass = desc.getClass(); Method[] descMethods = descClass.getMethods(); Method[] origMethods = origClass.getMethods(); boolean needExclude = false; //是否需要過濾部分欄位 if(!StringUtil.isEmpty(excludeFields)){ needExclude = true; excludeFields = "," + excludeFields.toLowerCase() + ","; } Map<String,Method> methodMap = new HashMap<String,Method>(); for (int i = 0; i < origMethods.length; i++) { Method method = origMethods[i]; String methodName = method.getName(); if (!methodName.equals("getClass") && methodName.startsWith("get") && (method.getParameterTypes() == null || method .getParameterTypes().length == 0)) { if(needExclude && excludeFields.indexOf(methodName.substring(3).toLowerCase()) > -1){ continue; } methodMap.put(methodName, method); } } for (int i = 0; i < descMethods.length; i++) { Method method = descMethods[i]; String methodName = method.getName(); if (!methodName.equals("getClass") && methodName.startsWith("get") && (method.getParameterTypes() == null || method .getParameterTypes().length == 0)) { if (methodMap.containsKey(methodName)) { Method origMethod = (Method) methodMap.get(methodName); try { if (method.getReturnType().equals( origMethod.getReturnType())) { Object returnObj = origMethod.invoke(orig, null); if(!isCopyNull && returnObj == null){ continue; } String field = methodName.substring(3); String setMethodName = "set" + field; Method setMethod = descClass.getMethod( setMethodName, new Class[] { method .getReturnType() }); setMethod.invoke(desc, new Object[] { returnObj }); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } } } /** * 兩物件之間的拷貝(在目標物件中存在的所有set方法,如果在源物件中存在對應的get方法,不管源物件的get方法的返回值是否為null,都進行拷貝) * 僅拷貝方法名及方法返回型別完全一樣的屬性值 * @param desc 目標物件 * @param orig 源物件 */ public static void copyPropertiesNotForce(Object desc, Object orig) { copyPropertiesNotForce(desc, orig, null); } /** * 兩物件之間的拷貝(在目標物件中存在的所有set方法,如果在源物件中存在對應的get方法,源物件的get方法的返回值為null的不拷貝) * 僅拷貝方法名及方法返回型別完全一樣的屬性值 * @param desc 目標物件 * @param orig 源物件 * @param excludeFields 不拷貝的field(多個用逗號隔開) */ public static void copyPropertiesNotNull(Object desc, Object orig) { copyPropertiesNotForce(desc, orig, null, false); } public static void copyPropertiesNotNull(Object desc, Object orig,String excludeFields) { copyPropertiesNotForce(desc, orig, excludeFields, false); } /** * 判斷兩個物件的所有相同屬性值是否相等,注意盡是比較相同的屬性,對於A物件屬性比B物件屬性多,如果相同屬性值相同,則返回為true * @param desc * @param orig * @return 相等返回true,否則返回false * @throws CrmBaseException */ public static boolean isEqualBeanProperties(Object desc, Object orig) throws CrmBaseException { String result= compareBeanProperties(desc,orig); if(result.equals("[]")) return true; return false; } /** * 比較兩個Bean相同欄位的值(以源物件的值為基準,json串中顯示目標物件中的值)【僅比較可轉換為string的型別】 * @param desc 目標物件 * @param orig 源物件 * @return String 不一致的欄位json串 * @throws ServiceException */ public static String compareBeanProperties(Object desc, Object orig) throws CrmBaseException { Map<String, Object> map = new HashMap<String, Object>(); Class<?> origClass = orig.getClass(); Class<?> descClass = desc.getClass(); Method[] descMethods = descClass.getMethods(); Method[] origMethods = origClass.getMethods(); Map<String,Method> methodMap = new HashMap<String,Method>(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < origMethods.length; i++) { Method method = origMethods[i]; String methodName = method.getName(); if (!methodName.equals("getClass") && methodName.startsWith("get") && (method.getParameterTypes() == null || method .getParameterTypes().length == 0)) { methodMap.put(methodName, method); } } for (int i = 0; i < descMethods.length; i++) { Method method = descMethods[i]; String methodName = method.getName(); if (!methodName.equals("getClass") && methodName.startsWith("get") && (method.getParameterTypes() == null || method .getParameterTypes().length == 0)) { if (methodMap.containsKey(methodName)) { Method origMethod = (Method) methodMap.get(methodName); try { if (method.getReturnType().equals( origMethod.getReturnType())) { Object origObj = origMethod.invoke(orig, null); origObj = origObj == null ? "" : origObj; Method descMethod = descClass.getMethod(methodName, null); Object descObj = descMethod.invoke(desc, null); descObj = descObj == null ? "" : descObj; if (!origObj.equals(descObj)) { map.put(methodName.substring(3), descObj); sb.append(",{'field':'"); sb.append(methodName.substring(3)); sb.append("','msg':'"); sb.append(descObj.toString().replaceAll("\'", "")); sb.append("'}"); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } } String str = "["; if (sb.length() > 0) { str += sb.substring(1); } return str + "]"; } /** * bean轉Map * @param bean * @return */ public static Map beanToMap(Object bean){ //return bean2Map(bean); return objectToMap(bean); } /** * 通過欄位名獲取方法陣列 * @param beanClass Class<?> * @param fieldNameArray 要輸出的所有欄位名陣列 * @return Method[] */ public static Method[] getMethods(Class<?> beanClass,String[] fieldNameArray){ Method[] methodArray = new Method[fieldNameArray.length]; String methodName; String fieldName; for (int i=0;i<fieldNameArray.length;i++) { Method method = null; fieldName = fieldNameArray[i]; methodName = fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); try { method = beanClass.getMethod("get"+methodName, null); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { try { method = beanClass.getMethod("is"+methodName, null); } catch (SecurityException e1) { e1.printStackTrace(); } catch (NoSuchMethodException e1) { e1.printStackTrace(); } } methodArray[i] = method; } return methodArray; } private static <K, V> Map<K, V> bean2Map(Object javaBean) { Map<K, V> ret = new HashMap<K, V>(); try { Method[] methods = javaBean.getClass().getDeclaredMethods(); for (Method method : methods) { if (method.getName().startsWith("get")) { String field = method.getName(); field = field.substring(field.indexOf("get") + 3); field = field.toLowerCase().charAt(0) + field.substring(1); Object value = method.invoke(javaBean, (Object[]) null); ret.put((K) field, (V) (null == value ? "" : value)); } } } catch (Exception e) { } return ret; } public static Map objectToMap(Object o){ return objectToMap(o, ""); } private static Map objectToMap(Object o, String prefix) { Map ret = new HashMap(); if (o == null) return ret; try { Map objDesc = PropertyUtils.describe(o); prefix = (!("".equals(prefix))) ? prefix + "." : ""; for (Iterator it = objDesc.keySet().iterator(); it.hasNext(); ) { String key = it.next().toString(); Object val = objDesc.get(key); if ((val != null) && (val instanceof CrmValueObject) && (!(o.equals(val)))) { ret.putAll(objectToMap(val, prefix + key)); break; } ret.put(prefix + key, val); } } catch (Exception e) { e.printStackTrace(); //logger.error(e); } //logger.debug("Object " + o + " convert to map: " + ret); return ret; } public static Map objectToMap(List fieldNameList, Object object) { Map ret = new HashMap(); for (Iterator it = fieldNameList.iterator(); it.hasNext(); ) { String fieldName = (String)it.next(); String[] fs = fieldName.split(quote(".")); try { Object o = object; for (int i = 0; i < fs.length; ++i) { Map objDesc = PropertyUtils.describe(o); o = objDesc.get(fs[i]); if (o == null) break; } ret.put(fieldName, o); } catch (Exception e) { e.printStackTrace(); //logger.error(e); } } return ret; } public static String quote(String s) { int slashEIndex = s.indexOf("\\E"); if (slashEIndex == -1) return "\\Q" + s + "\\E"; StringBuffer sb = new StringBuffer(s.length() * 2); sb.append("\\Q"); slashEIndex = 0; int current = 0; while ((slashEIndex = s.indexOf("\\E", current)) != -1) { sb.append(s.substring(current, slashEIndex)); current = slashEIndex + 2; sb.append("\\E\\\\E\\Q"); } sb.append(s.substring(current, s.length())); sb.append("\\E"); return sb.toString(); } }