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 }