在前台小系统或者页面中FORM表单中需要提交的数据很少的时候,在后台接受这些参数也无可厚非,不过等一个系统做完以后,我们突然发现,我们花了很多的时间去接受参数,做的多了,就会突然觉得 接受参数这个东西绝对是个体力活,而且格式比较固定,做多了就感觉腻歪了!
所以,本着“懒人改变世界”的观点,我准备看看JFinal的底层都做了些啥,这样就可以更好的了解这个框架,和使用这个框架,好了,废话不说,直接开八!
这个JFinal中我觉得我用得最爽的就是这个方法:
getModel(Code.class)
为什么这么说了,因为用了这个方法以后,我就不用重复的去接受前台传来的参数,然后一个一个的进行赋值,有这些时间,我估计我的电影都看完了。我们来看看这个方法里面都做些啥!!
打开这个方法:
public T getModel(Class modelClass) {
return (T)ModelInjector.inject(modelClass, request, false);
}
可以看到 ,他用一个ModelInjector.inject()这么个方法,继续走到这个方法里面,我们可以看到以下的方法:
public static T inject(Class modelClass, HttpServletRequest request, boolean skipConvertError) {
String modelName = modelClass.getSimpleName();
return inject(modelClass, StringKit.firstCharToLowerCase(modelName), request, skipConvertError);
}
在这个方法中,我们可以看到他做了两个操作,一个是去传入类名的简单类名。一个就是返回inject的值,还没有到底,接着打开这个方法,代码如下:
public static final T inject(Class modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) {
Object model = null;
try {
model = modelClass.newInstance();
} catch (Exception e) {
throw new ModelInjectException(e);
}
if (model instanceof Model)
injectActiveRecordModel((Model)model, modelName, request, skipConvertError);
else injectCommonModel(model, modelName, request, modelClass, skipConvertError);//就是一般的JavaBean
return (T)model;
}
你看到了什么? 对,你突然发现 Model是个Object,然后model是通过反射生成的,为什么要使用Object作为最初的Model的类型,我猜想是,因为我不知道传入的是什么东西,为了能够接受传入的所有类型,他使用了一个Object,不知道这么个猜想是不是对的,如果有错误,请留言更正啊!!在model被创建了以后,我们看到了它做了一个判断,看他是否为Model类型的实例,所以这样就是为什么我们定义的类要继承Model的原因吧!!好了 继续吧,重头戏就要来了,程序运行到这里就到了injectActiveRecordModel这个方法了,打开这个方法,我们可以看到如下的代码:
private static final void injectActiveRecordModel(Model model, String modelName, HttpServletRequest request, boolean skipConvertError) {
TableInfo tableInfo = TableInfoMapping.me().getTableInfo(model.getClass());
String modelNameAndDot = modelName + ".";
Map<String, String[]> parasMap = request.getParameterMap();
for (Entry<String, String[]> e : parasMap.entrySet()) {
String paraKey = e.getKey();
if (paraKey.startsWith(modelNameAndDot)) {
String paraName = paraKey.substring(modelNameAndDot.length());
Class colType = tableInfo.getColType(paraName);
if (colType == null)
throw new ActiveRecordException("The model attribute " + paraKey + " is not exists.");
String[] paraValue = e.getValue();
try {
// Object value = Converter.convert(colType, paraValue != null ? paraValue[0] : null);
Object value = paraValue[0] != null ? TypeConverter.convert(colType, paraValue[0]) : null;
model.set(paraName, value);
} catch (Exception ex) {
if (skipConvertError == false)
throw new ModelInjectException("Can not convert parameter: " + modelNameAndDot + paraName, ex);
}
}
}
}
}
简单的说下他干了些什么事情:
1、首先将上次传入的简单类名进行了简单的处理,在后面加了一个 “.”,这也就是为什么在我们在使用getModel这个方法的时候要使用“简单类名+.+数据库列字段”这么一种形式了
2、截取字符串,就是拿到数据库中的列字段,举个例子,加入我的某一个表单控件中的名字是“code.name”,那么他在截取了以后,就拿到了name这个字符串
3、判断再判断拿到这个控件中的值的类型,也就是这句话的作用
Class colType = tableInfo.getColType(paraName);
4、将获取到的值存入一个数字,然后在进行数据类型的转换。
5、最后就循环的使用model.set(paraName, value)来赋值
这样的话,就基本完成了接受参数,赋值的过程,当然 在数据的底层还进行了很多的操作 这个已经超出了今天讨论的话题了,以后有机会再开始八!!悄悄的说一下,其实对数据库的底层是使用PreparedStatement干的,再结合各种字符串拼接技术实现的!!
转自天蓬小猪http://my.oschina.net/u/257950/blog/131139