对象之间的转换,只转换属性名称和类型匹配的field,并且要求有setter getter
    *注:不能用使用Lombok的 @Accessors(chain = true) 注解
    包含功能:

    1. 单个转换(可以是两个不同class的类,只要属性、名称匹配,就可以转换)
    2. 集合转换
    3. copy 不为 null的属性
    4. 获得类的属性名和值 的Map
    5. 获得类和父类的属性名和值 的Map
    6. Map 转 Object
    1. package com.hq.pfexample.util;
    2. import org.springframework.beans.BeanUtils;
    3. import org.springframework.beans.BeanWrapper;
    4. import org.springframework.beans.BeanWrapperImpl;
    5. import org.springframework.cglib.beans.BeanCopier;
    6. import org.springframework.util.CollectionUtils;
    7. import java.beans.BeanInfo;
    8. import java.beans.Introspector;
    9. import java.beans.PropertyDescriptor;
    10. import java.lang.reflect.Field;
    11. import java.lang.reflect.Method;
    12. import java.util.*;
    13. import java.util.concurrent.ConcurrentHashMap;
    14. /**
    15. * @author zhangzuhao
    16. * @Description: 对象之间的转换,只转换属性名称和类型匹配的field,并且要求有setter getter
    17. * @date 2020/9/25 9:41
    18. */
    19. public class BeanMapperUtil {
    20. /**
    21. * 缓存coper
    22. */
    23. public static Map<String, BeanCopier> beanCopierMap = new ConcurrentHashMap<>();
    24. /**
    25. * @param source
    26. * @param target
    27. * @return
    28. */
    29. private static String generateKey(Class<?> source, Class<?> target) {
    30. return source.toString() + target.toString();
    31. }
    32. /**
    33. * 单个转换
    34. *
    35. * @param source
    36. * @param destinationClass
    37. * @param <T>
    38. * @return
    39. */
    40. public static <T> T map(Object source, Class<T> destinationClass) {
    41. if (source == null) {
    42. return null;
    43. }
    44. try {
    45. T instance = destinationClass.newInstance();
    46. copyProperties(source, instance);
    47. return instance;
    48. } catch (Throwable e) {
    49. return null;
    50. }
    51. }
    52. /**
    53. * 集合转换
    54. *
    55. * @param sourceList
    56. * @param destinationClass
    57. * @param <T>
    58. * @return
    59. */
    60. public static <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {
    61. List<T> destinationList = new ArrayList<>();
    62. if (CollectionUtils.isEmpty(sourceList)) {
    63. return destinationList;
    64. }
    65. for (Object sourceObject : sourceList) {
    66. T cur = map(sourceObject, destinationClass);
    67. destinationList.add(cur);
    68. }
    69. return destinationList;
    70. }
    71. /**
    72. * @param source
    73. * @param target
    74. */
    75. public static void copyProperties(Object source, Object target) {
    76. String beanKey = generateKey(source.getClass(), target.getClass());
    77. BeanCopier copier;
    78. if (!beanCopierMap.containsKey(beanKey)) {
    79. copier = BeanCopier.create(source.getClass(), target.getClass(), false);
    80. beanCopierMap.put(beanKey, copier);
    81. } else {
    82. copier = beanCopierMap.get(beanKey);
    83. }
    84. copier.copy(source, target, null);
    85. }
    86. /**
    87. * copy 不为 null的 .
    88. *
    89. * @param source
    90. * @param target
    91. */
    92. public static void copyNotNullProperties(Object source, Object target) {
    93. BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    94. }
    95. public static String[] getNullPropertyNames(Object source) {
    96. final BeanWrapper src = new BeanWrapperImpl(source);
    97. PropertyDescriptor[] pds = src.getPropertyDescriptors();
    98. Set<String> emptyNames = new HashSet<String>();
    99. for (PropertyDescriptor pd : pds) {
    100. Object srcValue = src.getPropertyValue(pd.getName());
    101. if (srcValue == null) emptyNames.add(pd.getName());
    102. }
    103. String[] result = new String[emptyNames.size()];
    104. return emptyNames.toArray(result);
    105. }
    106. /**
    107. * 获取利用反射获取类里面的值和名称
    108. *
    109. * @param obj
    110. * @return
    111. */
    112. public static HashMap<String, Object> objectToMap(Object obj) {
    113. HashMap<String, Object> map = new HashMap<>();
    114. Class<?> clazz = obj.getClass();
    115. if (classToMap(obj, map, clazz)) return map;
    116. return new HashMap<>();
    117. }
    118. public static HashMap<String, Object> objectAndSuperClassToMap(Object obj) {
    119. HashMap<String, Object> map = new HashMap<>();
    120. Class<?> clazz = obj.getClass();
    121. Class superclass = obj.getClass().getSuperclass();
    122. if (classToMap(obj, map, clazz) && classToMap(obj, map, superclass)) {
    123. return map;
    124. }
    125. return new HashMap<>();
    126. }
    127. private static boolean classToMap(Object obj, HashMap<String, Object> map, Class<?> clazz) {
    128. for (Field field : clazz.getDeclaredFields()) {
    129. field.setAccessible(true);
    130. String fieldName = field.getName();
    131. Object value;
    132. try {
    133. value = field.get(obj);
    134. } catch (IllegalAccessException e) {
    135. return false;
    136. }
    137. map.put(fieldName, value);
    138. }
    139. return true;
    140. }
    141. public static <T> T mapToObject(Map<String, Object> map, Class<?> beanClass) {
    142. if (map == null)
    143. return null;
    144. Object obj = null;
    145. try {
    146. obj = beanClass.newInstance();
    147. BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
    148. PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    149. for (PropertyDescriptor property : propertyDescriptors) {
    150. Method setter = property.getWriteMethod();
    151. if (setter != null) {
    152. setter.invoke(obj, map.get(property.getName()));
    153. }
    154. }
    155. } catch (Exception e) {
    156. e.printStackTrace();
    157. }
    158. return (T) obj;
    159. }
    160. }