问题来源:http://www.oschina.net/question/203191_63769
这两天有空,就把它实现了下,代码如下:
首先在 com.jfinal.core.Controller 类中加入如下两个方法:
public <T> List<T> getModels(Class<T> modelClass) { return ModelInjector.injects(modelClass, getRequest(), false); } public <T> List<T> getModels(Class<T> modelClass, String modelName) { return ModelInjector.injects(modelClass, modelName, getRequest(), false); }
然后,在类com.jfinal.core.ModelInjector 中,加入如下方法:
public static <T> List<T> injects(Class<?> modelClass, HttpServletRequest request, boolean skipConvertError) { String modelName = modelClass.getSimpleName(); return injects(modelClass, StringKit.firstCharToLowerCase(modelName), request, skipConvertError); } @SuppressWarnings({ "unchecked"}) public static final <T> List<T> injects(Class<?> modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) { if(Model.class.isAssignableFrom(modelClass)) { return injectActiveRecordModels((Class<Model<?>>) modelClass, modelName, request, skipConvertError); }else return injectCommonModels(modelClass, modelName, request, skipConvertError); } @SuppressWarnings({ "unchecked" }) private static final <T> List<T> injectActiveRecordModels(final Class<Model<?>> modelClass, final String modelName, final HttpServletRequest request, final boolean skipConvertError) { TableInfo tableInfo = TableInfoMapping.me().getTableInfo(modelClass); List<T> list = new ArrayList<T>(); String modelNameAndLeft = modelName + "["; Map<String, String[]> parasMap = request.getParameterMap(); for (Entry<String, String[]> e : parasMap.entrySet()) { String paraKey = e.getKey(); if (paraKey.startsWith(modelNameAndLeft) ) { String paraName = paraKey.substring(paraKey.indexOf("]")+2); Class<?> colType = tableInfo.getColType(paraName); if (colType == null) throw new ActiveRecordException("The model attribute " + paraName + " is not exists."); String[] paraValue = e.getValue(); try { Object value = paraValue[0] != null ? TypeConverter.convert(colType, paraValue[0]) : null; int index = Integer.parseInt(paraKey.substring(paraKey.indexOf("[")+1, paraKey.indexOf("]"))); int listSize = list.size(); Model<?> model = null; if(listSize <= index) { //中间的部分添加成null。 int size = index - listSize; for(int i =0; i<size; i++) { list.add(listSize + i,null); } model = modelClass.newInstance(); list.add(index,(T) model); } else { model = (Model<?>) list.get(index); if(model == null) { model = modelClass.newInstance(); list.set(index, (T) model); } } model.set(paraName, value); } catch (Exception ex) { if (skipConvertError == false) throw new ModelInjectException("Can not convert parameter: " + paraKey, ex); } } } List<T> nullList = new ArrayList<T>(1); nullList.add(null); list.removeAll(nullList); return list; } @SuppressWarnings("unchecked") private static final <T> List<T> injectCommonModels(Class<?> modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) { Map<String,Class<?>> attrNames = getObjectSetAttrName(modelClass); List<T> list = new ArrayList<T>(); String modelNameAndLeft = modelName + "["; Map<String, String[]> parasMap = request.getParameterMap(); for (Entry<String, String[]> e : parasMap.entrySet()) { String paraKey = e.getKey(); if (paraKey.startsWith(modelNameAndLeft) ) { String paraName = paraKey.substring(paraKey.indexOf("]")+2); //判断这个字段是否是对象对应的set方法,并且只有一个参数。如果没有,则抛出异常 if(!attrNames.containsKey(paraName)) throw new ActiveRecordException("The object attribute " + paraName + " method is not exists."); String[] paraValue = e.getValue(); try { Object value = paraValue[0] != null ? TypeConverter.convert(attrNames.get(paraName), paraValue[0]) : null; int index = Integer.parseInt(paraKey.substring(paraKey.indexOf("[")+1, paraKey.indexOf("]"))); int listSize = list.size(); Object model = null; if(listSize <= index) { //中间的部分添加成null。 int size = index - listSize; for(int i =0; i<size; i++) { list.add(listSize + i,null); } model = modelClass.newInstance(); list.add(index,(T) model); } else { model = list.get(index); if(model == null) { model = modelClass.newInstance(); list.set(index, (T) model); } } //设置对象的方法的值 Method method = model.getClass().getMethod("set" + StringKit.firstCharToUpperCase(paraName), attrNames.get(paraName)); method.invoke(model, value); } catch (Exception ex) { if (skipConvertError == false) throw new ModelInjectException("Can not convert parameter: " + paraKey, ex); } } } List<T> nullList = new ArrayList<T>(1); nullList.add(null); list.removeAll(nullList); return list; } private static final Map<String,Class<?>> getObjectSetAttrName(Class<?> modelClass) { Map<String,Class<?>> attrNames = new HashMap<String,Class<?>>(); Method[] methods = modelClass.getMethods(); for (Method method : methods) { String methodName = method.getName(); //取出对应的set方法,并且只有一个参数。 if (methodName.startsWith("set") == false) // only setter method continue; Class<?>[] types = method.getParameterTypes(); if (types.length != 1) // only one parameter continue; String attrName = methodName.substring(3); attrNames.put(StringKit.firstCharToLowerCase(attrName), types[0]); } return attrNames; }
@JFinal ,有空过来指正一下。