当表单提交的内容过多 ,让懒惰的程序员一个个getParameter()是很让人抓狂的,所以自动注入表单域是mvc不可或缺的功能,另外,文件上传也是一个特殊的表单域,你想看到程序员发觉上传只需要注入就能完成功能时的那种欣喜吗 ? 我们一起做做看。
我们依然从最简单的开始做,慢慢的润色。
注入表单的思路比较简单:
1,在form里面的name需要设置成诸如userinfo.username这类的,userinfo表示注入的目标对象,username表示userinfo对象的属性。这个对象必须是Action里面声明的
2,MainServlet在接收表单时,从getParameterMap()得到所有表单域,拆分出目标对象和属性,通过反射执行set方法
注意:由于每个请求都会产生一个Action的新实例,所以在Action类的属性不会被多个请求共享,是线程安全的。
实现方式如下:
1,打开MainServlet,首先声明
handField方法用来处理注入功能。
方法体和详细注释如下:
我们依然从最简单的开始做,慢慢的润色。
注入表单的思路比较简单:
1,在form里面的name需要设置成诸如userinfo.username这类的,userinfo表示注入的目标对象,username表示userinfo对象的属性。这个对象必须是Action里面声明的
2,MainServlet在接收表单时,从getParameterMap()得到所有表单域,拆分出目标对象和属性,通过反射执行set方法
注意:由于每个请求都会产生一个Action的新实例,所以在Action类的属性不会被多个请求共享,是线程安全的。
实现方式如下:
1,打开MainServlet,首先声明
- Map<String,Object[]> paramMap = request.getParameterMap();
- //此map对象用来缓存单页面的目标注入对象,比如此页面有多个Userinfo的属性需要注入,不可能每次注入都要生成Userinfo对象,肯定得在同一个对象中注入(小细节)
- Map<String, Object> fieldMap = new HashMap<String, Object>();
- 得到请求信息后进行迭代
- Set<Entry<String,Object[]>> paramSet = paramMap.entrySet();
- for (Entry<String,Object[]> ent : paramSet) {
- String paramName = (String) ent.getKey();
- Object[] paramValue = ent.getValue();
- handField(fieldMap,paramName,paramValue,action);
- }
Map<String,Object[]> paramMap = request.getParameterMap();
//此map对象用来缓存单页面的目标注入对象,比如此页面有多个Userinfo的属性需要注入,不可能每次注入都要生成Userinfo对象,肯定得在同一个对象中注入(小细节)
Map<String, Object> fieldMap = new HashMap<String, Object>();
得到请求信息后进行迭代
Set<Entry<String,Object[]>> paramSet = paramMap.entrySet();
for (Entry<String,Object[]> ent : paramSet) {
String paramName = (String) ent.getKey();
Object[] paramValue = ent.getValue();
handField(fieldMap,paramName,paramValue,action);
}
handField方法用来处理注入功能。
方法体和详细注释如下:
- //.这个字符是不能直接用正则的,需要转义
- String[] paramVos = paramName.split("\\.");
- //这里只支持 对象.属性的表单注入,对于多级的大家可以自行实现,相信不是难事儿。
- if (paramVos. length == 2) {
- Class actionClass = action.getClass();
- Object fieldObj = fieldMap.get(paramVos[0]);
- //从你的action得到目标注入对象
- Field field = actionClass.getDeclaredField(paramVos[0]);;
- if (fieldObj == null) {
- //假如是第一次注入,为空,则实例化目标对象
- Class fieldClass = field.getType();
- fieldObj = fieldClass.newInstance();
- //放入缓存,第二次直接从缓存取,保证同一个form注入的是同一个对象
- fieldMap.put(paramVos[0], fieldObj);
- }
- //构造目标属性的set方法
- String setMethod = "set"
- + paramVos[1].substring(0, 1).toUpperCase()
- + paramVos[1].substring(1);
- Field fieldField = null;
- fieldField = fieldObj.getClass().getDeclaredField(
- paramVos[1]);
- if(realValue!= null){
- InvocakeHelp. invokeMethod(fieldObj, setMethod,
- new Object[] { paramValue });
- }
- }
//.这个字符是不能直接用正则的,需要转义
String[] paramVos = paramName.split("\\.");
//这里只支持 对象.属性的表单注入,对于多级的大家可以自行实现,相信不是难事儿。
if (paramVos. length == 2) {
Class actionClass = action.getClass();
Object fieldObj = fieldMap.get(paramVos[0]);
//从你的action得到目标注入对象
Field field = actionClass.getDeclaredField(paramVos[0]);;
if (fieldObj == null) {
//假如是第一次注入,为空,则实例化目标对象
Class fieldClass = field.getType();
fieldObj = fieldClass.newInstance();
//放入缓存,第二次直接从缓存取,保证同一个form注入的是同一个对象
fieldMap.put(paramVos[0], fieldObj);
}
//构造目标属性的set方法
String setMethod = "set"
+ paramVos[1].substring(0, 1).toUpperCase()
+ paramVos[1].substring(1);
Field fieldField = null;
fieldField = fieldObj.getClass().getDeclaredField(
paramVos[1]);
if(realValue!= null){
InvocakeHelp. invokeMethod(fieldObj, setMethod,
new Object[] { paramValue });
}
}
本文介绍了一种简化MVC中表单域注入与文件上传过程的方法,通过设置表单name属性为对象.属性形式,利用反射获取参数并注入到指定对象中,实现自动注入表单域功能。




494

被折叠的 条评论
为什么被折叠?



