1 import java.beans.PropertyDescriptor;
2 import java.lang.reflect.Method;
3 import java.text.SimpleDateFormat;
4 import java.util.*;
5
6 /**
7 * @author:yc
8 * @date 2018/07/13 20:14
9 * @Description:
10 */
11 public class ReflectUtil {
12 private static Map<Class, MyConvert> classMyConvertMap = new HashMap<>();
13
14 public static void registConvert(Class clazz, MyConvert convert) {
15 classMyConvertMap.put(clazz, convert);
16 }
17 private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
18
19 /**
20 * 当前方法的作用是将request中的参数封装到对象中
21 */
22 public static <T> T convertData(Map<String, String[]> map, Class<T> clazz) throws Exception {
23 //HttpServletRequest re;
24 //Map<String, String[]> map = re.getParameterMap();
25 //最终的目的是将map中的数据封装到clazz对应的类型对象上面,然后返回
26 T newInstance = clazz.newInstance();
27 //解析参数
28 //获取到每个参数的名字,然后将这个参数对应的值封装到这个对象上面的对应的属性上面
29 //1要求 form表单中的参数的名字必须和对象上面的属性名一致
30 Set<Map.Entry<String, String[]>> entrySet = map.entrySet();//获取到所有参数的键值对,而且这个的键就是参数的名字,也就是是对象上面对应的属性名
31
32 for (Map.Entry<String, String[]> entry : entrySet) {
33 //获取到key
34 String key = entry.getKey();
35 System.out.println("当前正在封装:" + key);
36 //根据key去找刚才我们用于封装参数的对象上面的与key的值一样的属性名
37 PropertyDescriptor descriptor = new PropertyDescriptor(key, clazz);
38 if (descriptor != null) {
39 //获取到set方法
40 Method writeMethod = descriptor.getWriteMethod();
41 //调用set方法,然后将这个key对应的值设置进去,那么就到了对象上面
42 //entry.getValue() form 表单中传递过来的与key对应的具体值,我们需要设置给对象
43 String[] value = entry.getValue();
44
45 //为了保证参数的长度或者类型是匹配的,我们需要将form表单传递过来的数据 转换成为对象setter方法相对应的参数类型
46 //获取setter的方法的参数类型
47
48 Class<?>[] parameterTypes = writeMethod.getParameterTypes();
49
50 //进行参数类型转换
51 if (parameterTypes.length >= 1) {
52 Class<?> type = parameterTypes[0];//获取到参数的类型,是一个Class
53 if (type == int.class || type == Integer.class) {
54 if (value == null || value.length != 1) {
55 throw new RuntimeException("参数:" + key + "的长度必须为1");
56 } else {
57 int parseInt = Integer.parseInt(value[0]);//[18,23,34] int age =18;
58 writeMethod.invoke(newInstance, parseInt);
59 }
60 } else if (type == String.class) {
61 if (value != null) {
62 writeMethod.invoke(newInstance, Arrays.toString(value).replace("[", "").replace("]", ""));
63 }
64 } else if (type == String[].class) {
65 //数组类型会抛出长度异常
66 //java反射规范中,数组参数的传递需要进行转换,转换为object[]
67 /* String[] strings = new String[value.length];
68 for (int i = 0; i < value.length; i++) {
69 strings[i]=value[i];
70 }
71 writeMethod.invoke(newInstance,strings);*/
72 writeMethod.invoke(newInstance, new Object[]{value});
73 } else if (type == int[].class || type == Integer[].class) {
74 //writeMethod.invoke(newInstance,new Object[]{value});
75 int[] ints = new int[value.length];
76 for (int i = 0; i < value.length; i++) {
77 ints[i] = Integer.parseInt(value[i]);
78 }
79 //如果是在这里手动new的对象,可以不用再转换为object[]
80 writeMethod.invoke(newInstance, ints);
81 } else if (type == Date.class || type == java.sql.Date.class) {
82 if (value == null || value.length != 1) {
83 throw new RuntimeException("参数:" + key + "的长度必须为1");
84 } else {
85 MyConvert convert = classMyConvertMap.get(type);
86 if (convert != null) {
87 Object o = convert.convert(value[0]);
88 writeMethod.invoke(newInstance, o);
89 } else {
90 Date date = simpleDateFormat.parse(value[0]);
91 writeMethod.invoke(newInstance, date);
92 }
93 }
94 } else {//如果是其他的我们不知道的类型,请自己提供转换器转换
95 MyConvert convert = classMyConvertMap.get(type);//获取当前类型的转换器器
96 if (convert != null) {
97 Object o = convert.convert(value);//对数据进行转换
98 writeMethod.invoke(newInstance, o);
99 }
100 }
101 }
102 }
103 }
104 //返回带有数据的对象,也就是我们创建的对象
105 return newInstance;
106 }
107 }