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 }