java Bean之间的转换(属性名不同)

原文文章: https://blog.csdn.net/luliuliu1234/article/details/84141595

相同属性名时转换:

import org.springframework.beans.BeanUtils;
test1 a = new test1();
test2 b = new test2();
BeanUtils.copyProperties(a, b);

封装的Beanutils:

  1 package com.zhiwei.common.utils.bean;
  2 
  3 import java.lang.reflect.Method;
  4 import java.util.ArrayList;
  5 import java.util.List;
  6 import java.util.regex.Matcher;
  7 import java.util.regex.Pattern;
  8 
  9 /**
 10  * Bean 工具类
 11  *
 12  * @author zhiwei
 13  */
 14 public class BeanUtils extends org.springframework.beans.BeanUtils {
 15     /**
 16      * Bean方法名中属性名开始的下标
 17      */
 18     private static final int BEAN_METHOD_PROP_INDEX = 3;
 19 
 20     /**
 21      * 匹配getter方法的正则表达式
 22      */
 23     private static final Pattern GET_PATTERN = Pattern.compile("get(\p{javaUpperCase}\w*)");
 24 
 25     /**
 26      * 匹配setter方法的正则表达式
 27      */
 28     private static final Pattern SET_PATTERN = Pattern.compile("set(\p{javaUpperCase}\w*)");
 29 
 30     /**
 31      * Bean属性复制工具方法。
 32      *
 33      * @param dest 目标对象
 34      * @param src  源对象
 35      */
 36     public static void copyBeanProp(Object dest, Object src) {
 37         try {
 38             copyProperties(src, dest);
 39         } catch (Exception e) {
 40             e.printStackTrace();
 41         }
 42     }
 43 
 44     /**
 45      * 获取对象的setter方法。
 46      *
 47      * @param obj 对象
 48      * @return 对象的setter方法列表
 49      */
 50     public static List<Method> getSetterMethods(Object obj) {
 51         // setter方法列表
 52         List<Method> setterMethods = new ArrayList<Method>();
 53 
 54         // 获取所有方法
 55         Method[] methods = obj.getClass().getMethods();
 56 
 57         // 查找setter方法
 58 
 59         for (Method method : methods) {
 60             Matcher m = SET_PATTERN.matcher(method.getName());
 61             if (m.matches() && (method.getParameterTypes().length == 1)) {
 62                 setterMethods.add(method);
 63             }
 64         }
 65         // 返回setter方法列表
 66         return setterMethods;
 67     }
 68 
 69     /**
 70      * 获取对象的getter方法。
 71      *
 72      * @param obj 对象
 73      * @return 对象的getter方法列表
 74      */
 75 
 76     public static List<Method> getGetterMethods(Object obj) {
 77         // getter方法列表
 78         List<Method> getterMethods = new ArrayList<Method>();
 79         // 获取所有方法
 80         Method[] methods = obj.getClass().getMethods();
 81         // 查找getter方法
 82         for (Method method : methods) {
 83             Matcher m = GET_PATTERN.matcher(method.getName());
 84             if (m.matches() && (method.getParameterTypes().length == 0)) {
 85                 getterMethods.add(method);
 86             }
 87         }
 88         // 返回getter方法列表
 89         return getterMethods;
 90     }
 91 
 92     /**
 93      * 检查Bean方法名中的属性名是否相等。<br>
 94      * 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
 95      *
 96      * @param m1 方法名1
 97      * @param m2 方法名2
 98      * @return 属性名一样返回true,否则返回false
 99      */
100 
101     public static boolean isMethodPropEquals(String m1, String m2) {
102         return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
103     }
104 }

不同属性名时转换:

  两种方式,第一种 使用cglib进行动态生成,缺点:  需要手动维护映射关系。

                    第二种 java8函数式接口,缺点: 不同bean之间进行转换就需要写一个转换方法

  第一种方式

    首先加入依赖:

 1 <dependency>  
 2             <groupId>asm</groupId>  
 3             <artifactId>asm</artifactId>  
 4             <version>3.3.1</version>  
 5         </dependency>  
 6         <dependency>  
 7             <groupId>asm</groupId>  
 8             <artifactId>asm-commons</artifactId>  
 9             <version>3.3.1</version>  
10         </dependency>  
11         <dependency>  
12             <groupId>asm</groupId>  
13             <artifactId>asm-util</artifactId>  
14             <version>3.3.1</version>  
15         </dependency>  
16         <dependency>  
17             <groupId>cglib</groupId>  
18             <artifactId>cglib-nodep</artifactId>  
19             <version>2.2.2</version>  
20         </dependency>  

      CglibBean:

 1 package com.zhiwei.common.utils.bean;
 2 
 3 import org.springframework.cglib.beans.BeanGenerator;
 4 import org.springframework.cglib.beans.BeanMap;
 5 
 6 import java.util.Iterator;
 7 import java.util.Map;
 8 import java.util.Set;
 9 
10 /**
11  * CglibBean   class
12  *
13  * @author zhiwei
14  * @date 2020/09/28
15  */
16 public class CglibBean {
17     /**
18      * 实体Object
19      */
20     public Object object = null;
21     /**
22      * 属性map
23      */
24     public BeanMap beanMap = null;
25 
26     public CglibBean() {
27     }
28 
29     public CglibBean(Map<String, Class> propertyMap) {
30         this.object = generateBean(propertyMap);
31         this.beanMap = BeanMap.create(this.object);
32     }
33 
34     /**
35      * 给bean属性赋值
36      *
37      * @param property
38      * @param value
39      */
40     public void setValue(String property, Object value) {
41         beanMap.put(property, value);
42     }
43 
44     /**
45      * 通过属性名得到属性值
46      *
47      * @param property
48      * @return
49      */
50     public Object getValue(String property) {
51         return beanMap.get(property);
52     }
53 
54     /**
55      * 得到该实体bean对象
56      *
57      * @return
58      */
59     public Object getObject() {
60         return this.object;
61     }
62 
63     /**
64      * 创建cglib动态代理的bean
65      *
66      * @param propertyMap 通过map创建
67      * @return 返回bean对象
68      */
69     @SuppressWarnings("rawtypes")
70     private Object generateBean(Map<String, Class> propertyMap) {
71         BeanGenerator generator = new BeanGenerator();
72         Set keySet = propertyMap.keySet();
73         for (Iterator i = keySet.iterator(); i.hasNext(); ) {
74             String key = (String) i.next();
75             generator.addProperty(key, (Class) propertyMap.get(key));
76         }
77         return generator.create();
78     }
79 }

    CglibBeanUtils:

  1 package com.zhiwei.common.utils.bean;
  2 
  3 import com.fasterxml.jackson.databind.DeserializationFeature;
  4 import com.fasterxml.jackson.databind.JavaType;
  5 import com.fasterxml.jackson.databind.ObjectMapper;
  6 import org.apache.commons.beanutils.PropertyUtils;
  7 
  8 import java.io.IOException;
  9 import java.lang.reflect.Field;
 10 import java.lang.reflect.InvocationTargetException;
 11 import java.util.HashMap;
 12 import java.util.Map;
 13 
 14 /**
 15  * CglibBeanUtils   class
 16  *
 17  * @author zhiwei
 18  * @date 2020/09/28
 19  */
 20 public class CglibBeanUtils {
 21     private static final ObjectMapper mapper = new ObjectMapper();
 22 
 23     static {
 24         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
 25     }
 26 
 27     /**
 28      * 根据源对象content转换成目标对象,源对象支持集合类型,但源对象中的实体类和目标对象中的实体类需要属性名相同
 29      *
 30      * @param content 源对象
 31      * @param source  需要转换的目标集合类型
 32      * @param param   目标集合类型里封装的实体类
 33      * @return
 34      */
 35     public static <T> T getCollectionBean(Object content, Class<?> collectionClass, Class<?>... elementClasses) {
 36         if (content == null) {
 37             return null;
 38         }
 39         String contentStr = null;
 40         try {
 41             contentStr = mapper.writeValueAsString(content);
 42             JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
 43             return mapper.readValue(contentStr, javaType);
 44         } catch (IllegalArgumentException | IOException e) {
 45         }
 46         return null;
 47     }
 48 
 49     /**
 50      * 根据源对象obj转换成目标对象,不支持集合类型,源对象和目标对象属性名需要相同
 51      *
 52      * @param obj源对象
 53      * @param valueType需要转换的目标集合类型
 54      * @return
 55      */
 56     public static <T> T getDataBeanWithType(Object obj, Class<T> valueType) {
 57         String dataNode = null;
 58         try {
 59             dataNode = mapper.writeValueAsString(obj);
 60             return mapper.readValue(dataNode, valueType);
 61         } catch (IOException e) {
 62         }
 63         return null;
 64     }
 65 
 66     /**
 67      * 拷贝bean的不同名称之间属性值,
 68      * 需要手工维护一个bean之间不同属性名的映射关系,不支持源对象或目标对象为集合类型
 69      *
 70      * @param target 目标对象
 71      * @param source 源对象
 72      * @param param  源对象和目标对象的映射关系,其中key为源对象的属性名,value为目标对象的属性名
 73      * @return 目标对象
 74      * @throws ClassNotFoundException
 75      * @throws IllegalArgumentException
 76      * @throws IllegalAccessException
 77      * @throws InvocationTargetException
 78      * @throws NoSuchMethodException
 79      */
 80     @SuppressWarnings("rawtypes")
 81     public static Object getObject(Object target, Object source, Map<String, String> param) throws ClassNotFoundException,
 82             IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
 83         //获取源对象的属性名和值,属性名作为key,值作为value
 84         Map<String, Object> sourceBeanMap = PropertyUtils.describe(source);
 85         // 获取实体对象属性名数组
 86         Field[] fields = source.getClass().getDeclaredFields();
 87         // 属性名,属性类型
 88         Map<String, Class> temp = new HashMap<>();
 89         // 属性名,属性值
 90         Map<String, Object> valueParam = new HashMap<>();
 91         for (Field f : fields) {
 92             // 设置访问权限,否则不能访问私有化属性
 93             f.setAccessible(true);
 94             // 若没有映射关系,则跳过继续寻找有映射关系的属性
 95             if (null == param.get(f.getName()))
 96                 continue;
 97             temp.put(param.get(f.getName()), Class.forName(f.getType().getName()));
 98             for (Map.Entry<String, String> entry : param.entrySet()) {
 99                 if (entry.getKey().equals(f.getName())) {
100                     Object value = sourceBeanMap.get(entry.getKey());
101                     valueParam.put(param.get(f.getName()), value);
102                     break;
103                 }
104             }
105         }
106         // 根据参数生成CglibBean对象
107         CglibBean cglibBean = new CglibBean(temp);
108         for (Map.Entry<String, Object> entry : valueParam.entrySet()) {
109             cglibBean.setValue(entry.getKey(), entry.getValue());
110         }
111         Object object = cglibBean.getObject();
112         /*// 用object给目标对象赋值
113         PropertyUtils.copyProperties(target, object);*/
114         BeanUtils.copyBeanProp(target, object);
115         return target;
116     }
117 
118     public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException,
119             IllegalAccessException, InvocationTargetException, NoSuchMethodException {
120         Map<String, String> mapping = new HashMap<>();
121         UserDTO source = new UserDTO();
122         UserVO target = new UserVO();
123         source.setUserName("expireDate");
124         source.setUserAge(11);
125         mapping.put("userName", "name");//source field,target field,
126         mapping.put("userAge", "age");
127         target = (UserVO) getObject(target, source, mapping);
128         System.out.println(target.toString());
129     }
130 }

    两个实体类:

 1 @Data
 2 @AllArgsConstructor
 3 @NoArgsConstructor
 4 @Accessors(chain = true)
 5 public class UserDTO {
 6     private String userName;
 7     private Integer userAge;
 8 }
 9 
10 
11 @Data
12 @AllArgsConstructor
13 @NoArgsConstructor
14 @Accessors(chain = true)
15 public class UserVO {
16     private String name;
17     private Integer age;
18 }

  第二种方式

使用jdk8函数式接口:

 1 public class UserDTO {
 2     private String userName;
 3     private Integer userAge;
 4 
 5     public String getUserName() {
 6         return userName;
 7     }
 8 
 9     public void setUserName(String userName) {
10         this.userName = userName;
11     }
12 
13     public Integer getUserAge() {
14         return userAge;
15     }
16 
17     public void setUserAge(Integer userAge) {
18         this.userAge = userAge;
19     }
20 
21         public UserDTO convert(){
22         return ((Function<UserDTO,UserVO>) userDto ->{
23             UserVO userVo = new UserVO();
24             userVo.setAge(userDto.getUserAge());
25             userVo.setName(userDto.getUserName());
26         })
27     }
28 }
原文地址:https://www.cnblogs.com/zhiweiXiaomu/p/13743739.html