|  | @@ -0,0 +1,400 @@
 | 
	
		
			
				|  |  | +package com.zswl.dataservicestarter.utils;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.core.JsonProcessingException;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.core.type.TypeReference;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.databind.DeserializationFeature;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.databind.JavaType;
 | 
	
		
			
				|  |  | +import com.fasterxml.jackson.databind.ObjectMapper;
 | 
	
		
			
				|  |  | +import com.zswl.dataservicestarter.domain.base.DataServiceSuperEntity;
 | 
	
		
			
				|  |  | +import com.zswl.dataservicestarter.helper.ApplicationContextHolder;
 | 
	
		
			
				|  |  | +import com.zswl.dataservicestarter.type.CommonEnum;
 | 
	
		
			
				|  |  | +import io.swagger.annotations.ApiModelProperty;
 | 
	
		
			
				|  |  | +import org.apache.commons.lang3.ObjectUtils;
 | 
	
		
			
				|  |  | +import org.slf4j.Logger;
 | 
	
		
			
				|  |  | +import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | +import org.springframework.beans.FatalBeanException;
 | 
	
		
			
				|  |  | +import org.springframework.cglib.beans.BeanMap;
 | 
	
		
			
				|  |  | +import org.springframework.util.ClassUtils;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.beans.Introspector;
 | 
	
		
			
				|  |  | +import java.beans.PropertyDescriptor;
 | 
	
		
			
				|  |  | +import java.lang.reflect.*;
 | 
	
		
			
				|  |  | +import java.util.*;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +public class BeanUtils extends org.springframework.beans.BeanUtils {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static Logger log = LoggerFactory.getLogger(BeanUtils.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 将对象属性转化为map结合
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public static <T> Map<String, Object> beanToMap(T bean) {
 | 
	
		
			
				|  |  | +        Map<String, Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +        if (bean != null) {
 | 
	
		
			
				|  |  | +            BeanMap beanMap = BeanMap.create(bean);
 | 
	
		
			
				|  |  | +            for (Object key : beanMap.keySet()) {
 | 
	
		
			
				|  |  | +                map.put(key + "", beanMap.get(key));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return map;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static <T> Map<String, Object> beanToMapBlockRef(T bean) {
 | 
	
		
			
				|  |  | +        Map<String, Object> data = new HashMap<>();
 | 
	
		
			
				|  |  | +        if (ObjectUtils.isNotEmpty(bean)) {
 | 
	
		
			
				|  |  | +            Map<String, Object> map = BeanMap.create(bean);
 | 
	
		
			
				|  |  | +            for (Map.Entry<String, Object> entry : map.entrySet()) {
 | 
	
		
			
				|  |  | +                String key = entry.getKey();
 | 
	
		
			
				|  |  | +                Object value = entry.getValue();
 | 
	
		
			
				|  |  | +                List<String> _keys = new ArrayList<>();
 | 
	
		
			
				|  |  | +                data.put(key, loopValue(value, _keys));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return data;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    protected static Object loopValue(Object value, List<String> _keys) {
 | 
	
		
			
				|  |  | +        if (value != null && isCustomObj(value)) {
 | 
	
		
			
				|  |  | +            if (isCglibObj(value)) {
 | 
	
		
			
				|  |  | +                return null;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            Map<String, Object> _map = BeanMap.create(value);
 | 
	
		
			
				|  |  | +            HashMap<String, Object> map = new HashMap<>();
 | 
	
		
			
				|  |  | +            for (Map.Entry<String, Object> entry : _map.entrySet()) {
 | 
	
		
			
				|  |  | +                if (!_keys.contains(entry.getKey())) {
 | 
	
		
			
				|  |  | +                    // prevent custom entity endless loop
 | 
	
		
			
				|  |  | +                    if (entry.getValue() != null && isCustomObj(entry.getValue())) {
 | 
	
		
			
				|  |  | +                        _keys.add(entry.getKey());
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    map.put(entry.getKey(), loopValue(entry.getValue(), _keys));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return map;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return value;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static boolean isCglibObj(Object value) {
 | 
	
		
			
				|  |  | +        String name = value.getClass().getName();
 | 
	
		
			
				|  |  | +        return name == null || name.contains(ClassUtils.CGLIB_CLASS_SEPARATOR);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 判断是否是自定义类型
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param value
 | 
	
		
			
				|  |  | +     * @return
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private static boolean isCustomObj(Object value) {
 | 
	
		
			
				|  |  | +        if (value == null) {
 | 
	
		
			
				|  |  | +            return true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        String _name = value.getClass().getName();
 | 
	
		
			
				|  |  | +        if (_name.startsWith("java.lang") || _name.startsWith("java.util") || _name.startsWith("java.math") || (value instanceof Enum)) {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static void copyPropertiesWithoutNull(Object source, Object target) {
 | 
	
		
			
				|  |  | +        if (source == null || target == null) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Class<?> actualEditable = target.getClass();
 | 
	
		
			
				|  |  | +        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
 | 
	
		
			
				|  |  | +        for (PropertyDescriptor targetPd : targetPds) {
 | 
	
		
			
				|  |  | +            if (targetPd.getWriteMethod() == null) {
 | 
	
		
			
				|  |  | +                continue;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                Object value = getValueFromSource(source, targetPd);
 | 
	
		
			
				|  |  | +                if (value == null) {
 | 
	
		
			
				|  |  | +                    continue;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (!isSimpleProperty(targetPd.getPropertyType()) && !targetPd.getPropertyType().isInterface()) {
 | 
	
		
			
				|  |  | +                    Object targetPdValue = targetPd.getReadMethod().invoke(target);
 | 
	
		
			
				|  |  | +                    targetPdValue = AopTargetUtil.getTarget(targetPdValue);
 | 
	
		
			
				|  |  | +                    if (targetPdValue == null) {
 | 
	
		
			
				|  |  | +                        targetPdValue = targetPd.getPropertyType().getDeclaredConstructor().newInstance();
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    copyPropertiesWithoutNull(value, targetPdValue);
 | 
	
		
			
				|  |  | +                    setValue(target, targetPd, targetPdValue);
 | 
	
		
			
				|  |  | +                } else if (targetPd.getPropertyType().isAssignableFrom(List.class)) {
 | 
	
		
			
				|  |  | +                    Class paramCls = getFieldActualType(actualEditable.getDeclaredField(targetPd.getName()));
 | 
	
		
			
				|  |  | +                    if (paramCls != null) {
 | 
	
		
			
				|  |  | +                        Object targetPdValue = convertListToList((List) value, paramCls);
 | 
	
		
			
				|  |  | +                        setValue(target, targetPd, targetPdValue);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    setValue(target, targetPd, value);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            } catch (Exception ex) {
 | 
	
		
			
				|  |  | +                throw new FatalBeanException("Could not copy properties from source to target", ex);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static void setValue(Object target, PropertyDescriptor targetPd, Object value) throws IllegalAccessException, InvocationTargetException {
 | 
	
		
			
				|  |  | +        if (value.getClass().isEnum() && targetPd.getPropertyType() == String.class) {
 | 
	
		
			
				|  |  | +            if (CommonEnum.class.isAssignableFrom(value.getClass())) {
 | 
	
		
			
				|  |  | +                CommonEnum commonEnum = (CommonEnum) value;
 | 
	
		
			
				|  |  | +                value = commonEnum.getRemark();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 这里判断以下value是否为空
 | 
	
		
			
				|  |  | +        if ("".equals(value)) {
 | 
	
		
			
				|  |  | +            value = null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (value != null) {
 | 
	
		
			
				|  |  | +            Method writeMethod = targetPd.getWriteMethod();
 | 
	
		
			
				|  |  | +            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
 | 
	
		
			
				|  |  | +                writeMethod.setAccessible(true);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            try {
 | 
	
		
			
				|  |  | +                writeMethod.invoke(target, value);
 | 
	
		
			
				|  |  | +            } catch (Exception e) {
 | 
	
		
			
				|  |  | +                log.error("复制属性出错,target object type:{},target property name:{},type:{},set value type:{}", target.getClass(), targetPd.getName(), targetPd.getPropertyType(), value.getClass());
 | 
	
		
			
				|  |  | +                throw e;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static <T> T mapToBean(Map map, T bean) {
 | 
	
		
			
				|  |  | +        BeanMap beanMap = BeanMap.create(bean);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        beanMap.putAll(map);
 | 
	
		
			
				|  |  | +        return bean;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static <T> List<T> convertListToList(List bList, TypeReference<List<T>> typeRef) {
 | 
	
		
			
				|  |  | +        if (bList == null) return null;
 | 
	
		
			
				|  |  | +        ObjectMapper objectMapper = ApplicationContextHolder.getContext().getBean(ObjectMapper.class);
 | 
	
		
			
				|  |  | +        List<T> list = null;
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            //objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 | 
	
		
			
				|  |  | +            String json = objectMapper.writeValueAsString(bList);
 | 
	
		
			
				|  |  | +            list = objectMapper.readValue(json, typeRef);
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            e.printStackTrace();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return list;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static <T> List<T> convertListToList(List bList, Class targetClass) {
 | 
	
		
			
				|  |  | +        if (bList == null) {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        List<T> list = null;
 | 
	
		
			
				|  |  | +        ObjectMapper objectMapper = ApplicationContextHolder.getContext().getBean(ObjectMapper.class);
 | 
	
		
			
				|  |  | +        if (targetClass == Map.class) {
 | 
	
		
			
				|  |  | +            targetClass = HashMap.class;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, targetClass);
 | 
	
		
			
				|  |  | +        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 | 
	
		
			
				|  |  | +        String json = null;
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            json = objectMapper.writeValueAsString(bList);
 | 
	
		
			
				|  |  | +            list = objectMapper.readValue(json, javaType);
 | 
	
		
			
				|  |  | +        } catch (JsonProcessingException e) {
 | 
	
		
			
				|  |  | +            throw new RuntimeException(e);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return list;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/*    public static <T> List<T> fastConvertListToList(List bList, Class targetClass) {
 | 
	
		
			
				|  |  | +        if (bList == null) {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String json = JSON.toJSONString(bList, JSONWriter.Feature.FieldBased,JSONWriter.Feature.ReferenceDetection,JSONWriter.Feature.LargeObject);
 | 
	
		
			
				|  |  | +        List<T> list = JSON.parseArray(json,targetClass);
 | 
	
		
			
				|  |  | +        return list;
 | 
	
		
			
				|  |  | +    }*/
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static <T> List<T> beanConvertListToList(List bList, Class<T> targetClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
 | 
	
		
			
				|  |  | +        if (bList == null) {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        List<T> list = new ArrayList<>(bList.size());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (Object source : bList) {
 | 
	
		
			
				|  |  | +            if (Map.class.equals(targetClass)) {
 | 
	
		
			
				|  |  | +                Map map = new HashMap();
 | 
	
		
			
				|  |  | +                copyPropertiesWithoutNull(source, map);
 | 
	
		
			
				|  |  | +                list.add((T) map);
 | 
	
		
			
				|  |  | +            } else if (targetClass.isEnum()) {
 | 
	
		
			
				|  |  | +                list.add((T) source);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                Constructor<T> constructor = targetClass.getDeclaredConstructor();
 | 
	
		
			
				|  |  | +                if (constructor != null) {
 | 
	
		
			
				|  |  | +                    T target = constructor.newInstance();
 | 
	
		
			
				|  |  | +                    copyPropertiesWithoutNull(source, target);
 | 
	
		
			
				|  |  | +                    list.add(target);
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    log.warn("复制对象没有默认构造参数,请检查,复制类:{}", targetClass.getName());
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return list;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static String getActualType(Object o, int index) {
 | 
	
		
			
				|  |  | +        Type clazz = o.getClass().getGenericSuperclass();
 | 
	
		
			
				|  |  | +        ParameterizedType pt = (ParameterizedType) clazz;
 | 
	
		
			
				|  |  | +        return pt.getActualTypeArguments()[index].toString();
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static Class getFieldActualType(Field field) {
 | 
	
		
			
				|  |  | +        Type genType = field.getGenericType();
 | 
	
		
			
				|  |  | +        if (genType == null) {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        } else if (genType instanceof ParameterizedType) {
 | 
	
		
			
				|  |  | +            ParameterizedType pt = (ParameterizedType) genType;
 | 
	
		
			
				|  |  | +            if (pt.getActualTypeArguments()[0] instanceof ParameterizedType) {
 | 
	
		
			
				|  |  | +                return (Class) ((ParameterizedType) pt.getActualTypeArguments()[0]).getRawType();
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                return (Class) pt.getActualTypeArguments()[0];
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    public static Object getValueFromSource(Object source, PropertyDescriptor targetPd) throws InvocationTargetException, IllegalAccessException {
 | 
	
		
			
				|  |  | +        Class sourceClass = source.getClass();
 | 
	
		
			
				|  |  | +        PropertyDescriptor sourcePd = getPropertyDescriptor(sourceClass, targetPd.getName());
 | 
	
		
			
				|  |  | +        if (sourcePd == null || sourcePd.getReadMethod() == null) {
 | 
	
		
			
				|  |  | +            Method readMethod = targetPd.getReadMethod();
 | 
	
		
			
				|  |  | +            if (readMethod != null) {
 | 
	
		
			
				|  |  | +                String readMethodName = readMethod.getName();
 | 
	
		
			
				|  |  | +                Method sourceReadMethod = findMethod(sourceClass, readMethodName);
 | 
	
		
			
				|  |  | +                if (sourceReadMethod != null && Modifier.isPublic(sourceReadMethod.getDeclaringClass().getModifiers())) {
 | 
	
		
			
				|  |  | +                    if (targetPd.getPropertyType().equals(sourceReadMethod.getReturnType())) {
 | 
	
		
			
				|  |  | +                        Object value = readMethod.invoke(source);
 | 
	
		
			
				|  |  | +                        return value;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return null;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        boolean changeAccess = false;
 | 
	
		
			
				|  |  | +        Method readMethod = sourcePd.getReadMethod();
 | 
	
		
			
				|  |  | +        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
 | 
	
		
			
				|  |  | +            readMethod.setAccessible(true);
 | 
	
		
			
				|  |  | +            changeAccess = true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        Object value = readMethod.invoke(source);
 | 
	
		
			
				|  |  | +        if (changeAccess) {
 | 
	
		
			
				|  |  | +            readMethod.setAccessible(false);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return value;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 比较两个实体属性值,返回一个boolean,true则表时两个对象中的属性值无差异
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param oldObject 进行属性比较的对象1
 | 
	
		
			
				|  |  | +     * @param newObject 进行属性比较的对象2
 | 
	
		
			
				|  |  | +     * @return 属性差异比较结果boolean
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public static boolean compareObject(Object oldObject, Object newObject) {
 | 
	
		
			
				|  |  | +        Map<String, Map<String, Object>> resultMap = compareFields(oldObject, newObject);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (resultMap.size() > 0) {
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            return true;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param oldObject 进行属性比较的对象1
 | 
	
		
			
				|  |  | +     * @param newObject 进行属性比较的对象2
 | 
	
		
			
				|  |  | +     * @return 属性差异比较结果map
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    public static Map<String, Map<String, Object>> compareFields(Object oldObject, Object newObject) {
 | 
	
		
			
				|  |  | +        Map<String, Map<String, Object>> map = new HashMap<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        try {
 | 
	
		
			
				|  |  | +            /**
 | 
	
		
			
				|  |  | +             * 只有两个对象都是同一类型的才有可比性
 | 
	
		
			
				|  |  | +             */
 | 
	
		
			
				|  |  | +            if (oldObject.getClass() == newObject.getClass()) {
 | 
	
		
			
				|  |  | +                Class clazz = oldObject.getClass();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                //获取object的所有属性
 | 
	
		
			
				|  |  | +                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz, Object.class).getPropertyDescriptors();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                for (PropertyDescriptor pd : pds) {
 | 
	
		
			
				|  |  | +                    //遍历获取属性名
 | 
	
		
			
				|  |  | +                    String name = pd.getName();
 | 
	
		
			
				|  |  | +                    String description = name;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    Field field = null;
 | 
	
		
			
				|  |  | +                    try {
 | 
	
		
			
				|  |  | +                        field = clazz.getDeclaredField(name);
 | 
	
		
			
				|  |  | +                    } catch (NoSuchFieldException nsee) {
 | 
	
		
			
				|  |  | +                        try {
 | 
	
		
			
				|  |  | +                            field = clazz.getSuperclass().getDeclaredField(name);
 | 
	
		
			
				|  |  | +                        } catch (NoSuchFieldException nse) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (field != null) {
 | 
	
		
			
				|  |  | +                        if (field.isAnnotationPresent(ApiModelProperty.class)) {
 | 
	
		
			
				|  |  | +                            ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
 | 
	
		
			
				|  |  | +                            description = apiModelProperty.value();
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    //获取属性的get方法
 | 
	
		
			
				|  |  | +                    Method readMethod = pd.getReadMethod();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    // 在oldObject上调用get方法等同于获得oldObject的属性值
 | 
	
		
			
				|  |  | +                    Object oldValue = readMethod.invoke(oldObject);
 | 
	
		
			
				|  |  | +                    // 在newObject上调用get方法等同于获得newObject的属性值
 | 
	
		
			
				|  |  | +                    Object newValue = readMethod.invoke(newObject);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (oldValue == null && newValue == null) {
 | 
	
		
			
				|  |  | +                        continue;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    if (oldValue instanceof List || newValue instanceof List) {
 | 
	
		
			
				|  |  | +                        continue;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    if (oldValue == null && newValue != null) {
 | 
	
		
			
				|  |  | +                        Map<String, Object> valueMap = new HashMap<>(2);
 | 
	
		
			
				|  |  | +                        valueMap.put("oldValue", oldValue);
 | 
	
		
			
				|  |  | +                        valueMap.put("newValue", newValue);
 | 
	
		
			
				|  |  | +                        map.put(description, valueMap);
 | 
	
		
			
				|  |  | +                    } else if (oldValue instanceof DataServiceSuperEntity && newValue instanceof DataServiceSuperEntity) {
 | 
	
		
			
				|  |  | +                        DataServiceSuperEntity oldSp = (DataServiceSuperEntity) oldValue;
 | 
	
		
			
				|  |  | +                        DataServiceSuperEntity newSp = (DataServiceSuperEntity) newValue;
 | 
	
		
			
				|  |  | +                        if (!Objects.equals(oldSp.getId(), newSp.getId())) {
 | 
	
		
			
				|  |  | +                            Map<String, Object> valueMap = new HashMap<>(2);
 | 
	
		
			
				|  |  | +                            valueMap.put("oldValue", oldValue);
 | 
	
		
			
				|  |  | +                            valueMap.put("newValue", newValue);
 | 
	
		
			
				|  |  | +                            map.put(description, valueMap);
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    } else if (!Objects.equals(oldValue, newValue)) {// 比较这两个值是否相等,不等就可以放入map了
 | 
	
		
			
				|  |  | +                        Map<String, Object> valueMap = new HashMap<>(2);
 | 
	
		
			
				|  |  | +                        valueMap.put("oldValue", oldValue);
 | 
	
		
			
				|  |  | +                        valueMap.put("newValue", newValue);
 | 
	
		
			
				|  |  | +                        map.put(description, valueMap);
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        } catch (Exception e) {
 | 
	
		
			
				|  |  | +            e.printStackTrace();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return map;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |