1. 程式人生 > 其它 >JavaWeb之如何把請求資料轉成實體類

JavaWeb之如何把請求資料轉成實體類

JavaWeb之如何把請求資料轉成實體類

  • 自己寫個工具類加入下面兩個靜態方法
  • 自定一個註解類DateTimeFormatting
  • 呼叫方式User user = util.ObjectFromMap(req.getParameterMap(), User.class)
  • 暫時支援8種基本資料型別對應包裝類、BigDecimaljava.util.Date,可應對大多情況,如有需求,可以自己新增
  • 暫不支援陣列
public static <T> T ObjectFromMap(Map<String,String[]> map, Class<T> type) {
    try {
        // 建立返回物件,是要轉換的物件
        T t = type.getConstructor().newInstance();
        
        // 遍歷map集合
        for (Map.Entry<String, String[]> entry : map.entrySet()) {
            // 獲得屬性名
            String key = entry.getKey();
            // 獲得屬性值
            String[] values = entry.getValue();

            // 自定義方法
            // 如果類中沒有這個屬性跳出[本次]迴圈
            if (!checkObjectHasField(type,key)) {
                continue;
            }
            
            // 獲取屬性描述物件,如果類中沒有這個屬性,報異常,所以要有上面那個操作
            PropertyDescriptor pd = new PropertyDescriptor(key,type);
            // 獲取屬性的set方法,所以對應屬性要有set方法
            Method method = pd.getWriteMethod();

            // 暫時不支援陣列
            String value = values[0];

            // req獲取的值都是字串,所以在對非字串型別要轉換
            // 獲取屬性的型別
            String propertyType = pd.getPropertyType().getName();
            // 如果字串長度為0 說明空串,valueOf會轉換失敗
            if(value.length() > 0) {
                switch (propertyType) {
                    case "java.lang.Byte":
                        method.invoke(t, Byte.valueOf(value));
                        break;
                    case "java.lang.Integer":
                        method.invoke(t, Integer.valueOf(value));
                        break;
                    case "java.lang.Short":
                        method.invoke(t, Short.valueOf(value));
                        break;
                    case "java.lang.Long":
                        method.invoke(t, Long.valueOf(value));
                        break;
                    case "java.lang.Float":
                        method.invoke(t, Float.valueOf(value));
                        break;
                    case "java.lang.Double":
                        method.invoke(t, Double.valueOf(value));
                        break;
                    case "java.lang.Boolean":
                        method.invoke(t, Boolean.valueOf(value));
                        break;
                    case "java.lang.Character":
                        method.invoke(t, value.charAt(0));
                        break;
                    case "java.lang.String":
                        method.invoke(t, value);
                        break;
                    case "java.math.BigDecimal":
                        method.invoke(t, new BigDecimal(value));
                        break;
                    case "java.util.Date":
                        // 預設使用格式化日期的格式
                        String format = "yyyy-MM-dd";
                        // 獲取屬性物件
                        Field field = type.getDeclaredField(key);
                        // 通過屬性物件獲取 DateTimeFormatting 註解
                        // 自定義註解
                        DateTimeFormatting anno = field.getAnnotation(DateTimeFormatting.class);
                        // 檢查註解存在否
                        if (anno != null) {
                            // 存在使用註解的 value 來格式化時間
                            // 不存在使用上面的預設格式
                            format = anno.value();
                        }
                        method.invoke(t, new SimpleDateFormat(format).parse(value));
                        break;
                    default:
                        break;
                }
            } else {
                // 如果字串是空串,那麼轉成的bean物件對應屬性也給個空串
                // 如果想給null可以去掉
                if (propertyType.equals("java.lang.String")) {
                    method.invoke(t, value);
                }
            }
        }
        return t;
    } catch (InstantiationException | IllegalAccessException
            | InvocationTargetException | NoSuchMethodException
            | IntrospectionException | NoSuchFieldException e
            | ParseException e) {
        e.printStackTrace();
    }
    return null;
}
  • 校驗物件中是否有指定屬性
/**
 * 校驗物件中是否有指定屬性
 * @param type 物件的型別
 * @param fieldName 屬性名
 * @return 是/否
 */
public static boolean checkObjectHasField(Class type,String fieldName) {
    Field[] fields = type.getDeclaredFields();
    for (Field field : fields) {
        if (field.getName().equals(fieldName)) {
            return true;
        }
    }
    return false;
}
  • DateTimeFormatting註解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DateTimeFormatting {
    String value() default "yyyy-MM-dd";
}