懒惰型(左优先)的from表单填充(相对于struts的右优先填充) StrutsF#J#ServletC
程序员文章站
2024-02-21 12:50:42
...
/** * 普通的写法,如: * <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. 代码意思,基本上可以看 变量命名就能看懂。