问题来源: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 ,有空过来指正一下。