反射の適用formフォームのデータを自動的にオブジェクトにカプセル化


私たちはよくフォームを提出して、たくさんのページから送られてきたパラメータをset方法でオブジェクトに割り当てます.
同じクラスの複数のオブジェクトを1つのフォームでコミットすることもよくあります.
1つのフォームで複数の異なるオブジェクトがコミットされる場合もあります.
 
反射を学んだ後、比較的通用するツール類を作りたいと思っています.上のことのために繰り返し労働をしないでください.
 
たとえば、ページには次の入力ボックスがあります.



 



 



 
ツールクラスを通じて、自動的にListを獲得することを望んで、このListは3つのPersonオブジェクトがあって、
Person 1 : Jack,10,1978-07-22
Person 2 : Mike,21,1989-07-21 05:33
Person 3 : Rose,22,1999-08-21 23:33:12
 
手順1-文字列を適切なデータ型に変更する準備
ページから伝わってくるのは、Stringですが、私たちのbeanの属性は、さまざまなデータ型です.
まず、Stringの値を必要なデータ型の値に変換する小さな方法を用意する必要があります.
 
 
public final static Map<String, String> toTypeMethods;
	static {
		//       :   boolean,byte,char,int,long,float,double        + String,java.util.Date,BigDecimal     
		toTypeMethods = new HashMap<String, String>();
		toTypeMethods.put("boolean", "toBoolean");
		toTypeMethods.put("byte", "toByte");
		toTypeMethods.put("char", "toString");
		toTypeMethods.put("character", "toString");
		toTypeMethods.put("string", "toString");
		toTypeMethods.put("int", "toInteger");
		toTypeMethods.put("integer", "toInteger");
		toTypeMethods.put("long", "toLong");
		toTypeMethods.put("float", "toFloat");
		toTypeMethods.put("double", "toDouble");
		toTypeMethods.put("date", "toDate");
		toTypeMethods.put("bigdecimal", "toBigDecimal");
	}

	/**
	 *         :        、   ,
         *                          。
	 *   :   Person birthday   Date,
         *     "2010-10-01"     Date   2010-10-01
	 *     birthday   int,    "2010-10-01",         null,
         *         ,             ,           
	 * @param field      
	 * @param string      
	 * @param  string         
	 */
	public static Object toTypeValue(Field field, String string)
			throws Exception{
			String fieldTypename = field.getType().getSimpleName(); //     (     )
			//       , map            ,        String                
			String methodName = toTypeMethods.get(fieldTypename.toLowerCase()); 
			//    
			Method method = 
				BeanReflectUtil.class.
				getDeclaredMethod(methodName, string.getClass()); 
			//    ,        
			return method.invoke(null, string); //          ,          obj   。       null。 
		}

	//             String                
	@SuppressWarnings("unused")
	private static Boolean toBoolean(final String s) {
		return NumberUtil.toBoolean(s, true);
	}
	@SuppressWarnings("unused")
	private static Byte toByte(final String s) {
		return NumberUtil.toByte(s, (byte)0);
	}

	@SuppressWarnings("unused")
	private static String toString(final String s) {
		return s;
	}

	@SuppressWarnings("unused")
	private static Integer toInteger(final String s) {
		return NumberUtil.toInt(s, 0);
	}
	@SuppressWarnings("unused")
	private static Long toLong(final String s) {
		return NumberUtil.toLong(s, 0);
	}
	@SuppressWarnings("unused")
	private static Float toFloat(String s) {
		return NumberUtil.toFloat(s, (float)0);
	}
	@SuppressWarnings("unused")
	private static Double toDouble(String s) {
		return NumberUtil.toDouble(s, 0.0);
	}
	@SuppressWarnings("unused")
	private static Date toDate(String s) { //        
		try {
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s);
		} catch(Exception e1) {
			try {
				return new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(s);
			}catch(Exception e2) {
				try {
					return new SimpleDateFormat("yyyy-MM-dd").parse(s);
				} catch (Exception e3) {
					return null;
				}
			}
		} 
	}

	@SuppressWarnings("unused")
	private static BigDecimal toBigDecimal(String s) {
		try {
			return new BigDecimal(s);
		} catch(Exception e) {
			return new BigDecimal(0);
		}
	}
 
 
    NumberUtil.toXXXはStringを他のデータ型に変換するために、それらの実現は簡単で、整形を例に挙げます.
/***
 *         
 * @param value  
 * @param defaultInt                 
 * @return
 */
public static int toInt(String value, int defaultInt) {
	int result = 0;
	try {
		result = Integer.parseInt(value);
	} catch(NumberFormatException e) {
		result = defaultInt;
	}
	return result;
}

 
使用方法:
今私はページで“20”を得て、“20”をageに与える必要があります
//           (1)  getter And Setter      :http://ivan0513.iteye.com/admin/blogs/728396
Person p = new Person();
//    "20"    Integer 20
Object age = toTypeValue(p.getClass().getDeclaredField("age"), "20");
//   20     Person age,        setAge  ,             ,
//                 。       。
//invokeSetMethod   BeanReflectUtil.java 
BeanReflectUtil.invokeSetMethod(Person.class, "age", p, age);
//    
System.out.println(p.getAge());

コンソールが印刷されます.
20 

 
上記のツールメソッドを完了すると、formフォームのパラメータを自動的にオブジェクトの集合にカプセル化する道から遠くありません.
ステップ2-ページのパラメータを取得し、戻りオブジェクトセットリストをカプセル化する
/***
 *         bean     
 *              
 * @param c              
 * return Map    ,     
 */
public static Map<String, String[]> getFieldValues(HttpServletRequest request, Class<?> c) {
 Map<String, String[]> fieldValues = new HashMap<String, String[]>();
//        
 String[] fieldNames = BeanReflectUtil.getDeclaredFieldNames(c);
 for(int i=0; i<fieldNames.length; i++) {
//    ,          
  String[] values = request.getParameterValues(fieldNames[i]);
  fieldValues.put(fieldNames[i], values);
 }
 return fieldValues;
}
/**
 *            
 *              
 * 1.                 ,     1 ,
 *  Person{name, age, birthday}    ,   <input type="text" name="age" value="20" />(      ,       )
 * 2.       ,           
 *  <input type="text" name="age" id="age1" />  <input type="text" name="name" id="name1" />
 * <input type="text" name="age" id="age2" /> <input type="text" name="name" id="name2" />
 *           , :
 * <input type="text" name="age" id="age1" />  <input type="text" name="name" id="name1" /> <input type="text" name="birthday" id="birthday1" />
 * <input type="text" name="age" id="age2" /> <input type="text" name="name" id="name2" /> <!-- 2 age,name,   1 birthday-->
 * @param fieldValues
 * @return
 */
public static int getParameterLenth(HttpServletRequest request, Class<?> c) {
 
 int parameterLenth = 0;
 String[] fieldNames = BeanReflectUtil.getDeclaredFieldNames(c);
 for(int i=0; i<fieldNames.length; i++) {
  String[] values = request.getParameterValues(fieldNames[i]);
  if(values != null) {
   parameterLenth = values.length;
   break;
  }
 }
 return parameterLenth;
}
/**
 *           bean,     bean
 * @param request
 * @param c
 * @return
 * @throws Exception
 * @throws NoSuchFieldException
 */
public static List<?> assembleObjectList(HttpServletRequest request, Class<?> c) 
 throws Exception, NoSuchFieldException {
 Object[] objArray = null;
 //1.      (    bean     )
 Map<String, String[]> fieldValues = getFieldValues(request, c);
 List objList = null;
 if(fieldValues != null) {
  //2.  bean   
  int objLength = getParameterLenth(request, c);
  objArray = new Object[objLength];
  objList = new ArrayList();
  //3.    
  for(int i=0; i<objLength; i++) {
   objArray[i] = c.newInstance();
   objList.add(objArray[i]);
  }
  //            (          )
  Iterator<String> keyIt = fieldValues.keySet().iterator();
  while(keyIt.hasNext()) {
   String fieldName = keyIt.next();
   Field field = c.getDeclaredField(fieldName); //         
   String[] fieldValue = fieldValues.get(fieldName); //      
   if(fieldValue != null) {
    for(int i=0; i<objArray.length; i++) { //  :        ,        (  set  )
     //1.     Set  
     Method m = BeanReflectUtil.assembleSetMethod(c, field);
     //2.    (String  )            
     Object fieldObj = BeanReflectUtil.toTypeValue(field, fieldValue[i]); 
     //3.  Set  
     m.invoke(objArray[i], fieldObj); //   objArray[i]  set  ,     field    fieldObj   
    }
   }
  }
 }
 
//  return objArray;
 return objList;
}

 
次の操作を行います.
ページにあるように:
<input type="text" name="age" id="age1" />  
<input type="text" name="name" id="name1" />
<input type="text" name="age" id="age2" /> 
<input type="text" name="name" id="name2" />
</form>

 
コミット後、バックグラウンドにListをカプセル化し、以下のコードのみを必要とします.
List<Person> list = (List<Person>) BaiscDataUtil.assembleObjectList(request, Person.class);