/**
* 普通的写法,如:
* <tb:code type="CODE_DevJobGrade" name="criterionForm" required="true" property="criterions.jobGrade" elementWidth="150" value="0"/>
* <tb:code type="CODE_DevJobGrade" name="criterionForm" required="true" property="criterions.jobGrade" elementWidth="150" value="0"/>
* 其中的两个 property="criterions.jobGrade" 会被struct解释为属性criterions的字符串JobGrade数组。<br/>
* 但是有些时候会需要解释为criterions的数组,值保持到criterion[0]的jobGrade属性中.
* so here it is.
* @param form
* @param request
* @return
* @author hite
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SecurityException
* @throws IllegalArgumentException
* @date 2009-12-21下午02:16:03
* @since 1.0.0
*/
public static boolean lazyPopulateForm(ActionForm form, HttpServletRequest request) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
//先循环反射,再循环变量
//HiteFix 应该做出迭代的
HashMap args = new HashMap();
for (Enumeration e = request.getParameterNames();e.hasMoreElements();){
String key = (String)e.nextElement();
String[] keys =key.split("\\.");
if (keys.length>1) {
if (args.containsKey(keys[0])) {
List kv = (List) args.get(keys[0]);
kv.add(keys[1]);
args.put(keys[0],kv);
} else {
List kv = new ArrayList();
kv.add(keys[1]);
args.put(keys[0],kv);
}
}
}
Class c=form.getClass();
Field []fs=c.getDeclaredFields();
for(int i=0;i<fs.length;i++){
Field f=fs[i];
String voArrayName = f.getName();
if(args.containsKey(voArrayName)){
f.setAccessible(true);
Class type = f.get(form).getClass();
if(type.isArray()){
List subArgs = (List)args.get(voArrayName);
if(subArgs.size()>0){
Class componentType = type.getComponentType();
String[] values = request.getParameterValues(voArrayName+"."+subArgs.get(0).toString());
//VO Array
Object[] filledArray = (Object[])Array.newInstance(componentType, values.length);
//TODO to VO
for (int k = 0; k < filledArray.length; k++) {
Object singleVO = filledArray[k];
if (singleVO == null) {
singleVO = componentType.getConstructor(null).newInstance(null);
}
Field[] svFields = singleVO.getClass().getDeclaredFields();
for (int j = 0; j < svFields.length; j++) {
Field svField = svFields[j];
String svFieldName = svField.getName();
if (subArgs.contains(svFieldName)) {
svField.setAccessible(true);
Method method;
String currentArgValue = request.getParameterValues(voArrayName + "." + svFieldName)[k];
if (currentArgValue.length()>0) {//not fill if null or empty
try {
Object svFieldValue = svField.get(singleVO);
if (svFieldValue == null) {
method = svField.getType().getMethod("getInstance", new Class[] { java.lang.String.class });
svFieldValue = method.invoke(singleVO, currentArgValue);
}
if (svFieldValue instanceof CodeType) {
svField.set(singleVO, svFieldValue);
}
} catch (NoSuchMethodException e2) {
if (svField.getType() == java.lang.String.class) {
svField.set(singleVO, currentArgValue);
} else if (svField.getType() == java.lang.Long.class) {
svField.set(singleVO, Long.parseLong(currentArgValue));
}
}
}
}
}
//finish filling a piece of vo
filledArray[k] = singleVO;
}
//finish filling a group of VOs
f.set(form, filledArray);
}
}
}
}
return false;
}
1. 目前做的只适合两级如
" property = 'criterion.grade' "
2. 参数也只有2个是servlet的,打算以后重构
3. 里面只考虑到有线的自定义类型和string别的没加
4. 代码意思,基本上可以看 变量命名就能看懂。