使用request获取表单中数据的方法
<input type="text" name="user.name"/>
String name = request.getParameter("user.name");
User user = new User();
user.setName(name);
1.JFinal中可以直接将表单的数据注入到Model中
User u = getModel(User.class);
getModel方法是继承自Controller,注入的具体实现在ModelInjector类中
/**
* Get model from http request.
*/
public <T> T getModel(Class<T> modelClass) {
return (T)ModelInjector.inject(modelClass, request, false);
}
2.ModelInjector 表单数据注入的具体实现类
通过传入的 model.class 得到 model类的所有方法,然后找到属性所对应的set方法,将request取到的值转换为对应的数据类型,最后把值赋给model类
final class ModelInjector {
public static <T> T inject(Class<?> modelClass, HttpServletRequest request, boolean skipConvertError) {
String modelName = modelClass.getSimpleName();
return inject(modelClass, StringKit.firstCharToLowerCase(modelName), request, skipConvertError);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static final <T> T inject(Class<?> modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) {
Object model = null;
try {
model = modelClass.newInstance();//采用反射创建一个model的实例
} catch (Exception e) {
throw new RuntimeException(e);
}
if (model instanceof Model)
injectActiveRecordModel((Model)model, modelName, request, skipConvertError);//继承Model类注入表单数据的实现
else
injectCommonModel(model, modelName, request, modelClass, skipConvertError);//普通Moedl类注入表单数据的实现
return (T)model;
}
private static final void injectCommonModel(Object model, String modelName, HttpServletRequest request, Class<?> modelClass, boolean skipConvertError) {
Method[] methods = modelClass.getMethods();//获得Model类的所有方法
for (Method method : methods) {
String methodName = method.getName();//方法名
//只有实现了属性对应的set方法并且传入的参数为一个的时候才能把form里的数据注入到对应的model属性上
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);
String value = request.getParameter(modelName + "." + StringKit.firstCharToLowerCase(attrName));//拼接出model.属性(JFinal默认form里数据名必须是类名.属性)这样才能用request取到对应的值
if (value != null) {
try {
method.invoke(model, TypeConverter.convert(types[0], value));//TypeConverter将value值转换成类属性对应的数据类型,执行model的method方法将value set到model的属性上
} catch (Exception e) {
if (skipConvertError == false)
throw new RuntimeException(e);
}
}
}
}
@SuppressWarnings("rawtypes")
private static final void injectActiveRecordModel(Model<?> model, String modelName, HttpServletRequest request, boolean skipConvertError) {
TableInfo tableInfo = TableInfoMapping.me().getTableInfo(model.getClass());//TableInfo保存有Model类的所有属性,相当于一个Model实例
String modelNameAndDot = modelName + ".";
Map<String, String[]> parasMap = request.getParameterMap();
for (Entry<String, String[]> e : parasMap.entrySet()) {//request中的数据是以key-value的方式保存的,遍历提交来form的所有数据
String paraKey = e.getKey();
if (paraKey.startsWith(modelNameAndDot)) {//满足“类.属性”格式的的数据才能被识别保存到model中
String paraName = paraKey.substring(modelNameAndDot.length());
Class colType = tableInfo.getColType(paraName);//从tableInfo中查找 属性对应的type
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);//保存数据到model里
} catch (Exception ex) {
if (skipConvertError == false)
throw new RuntimeException("Can not convert parameter: " + modelNameAndDot + paraName, ex);
}
}
}
}
}