动手开发自己的mvc-2----完善控制层,提供自动注入和注解上传等功能

本文介绍了一种简化MVC中表单域注入与文件上传过程的方法,通过设置表单name属性为对象.属性形式,利用反射获取参数并注入到指定对象中,实现自动注入表单域功能。
  当表单提交的内容过多 ,让懒惰的程序员一个个getParameter()是很让人抓狂的,所以自动注入表单域是mvc不可或缺的功能,另外,文件上传也是一个特殊的表单域,你想看到程序员发觉上传只需要注入就能完成功能时的那种欣喜吗  ? 我们一起做做看。
    我们依然从最简单的开始做,慢慢的润色。
    注入表单的思路比较简单:
    1,在form里面的name需要设置成诸如userinfo.username这类的,userinfo表示注入的目标对象,username表示userinfo对象的属性。这个对象必须是Action里面声明的
    2,MainServlet在接收表单时,从getParameterMap()得到所有表单域,拆分出目标对象和属性,通过反射执行set方法
  
注意:由于每个请求都会产生一个Action的新实例,所以在Action类的属性不会被多个请求共享,是线程安全的。

实现方式如下:
1,打开MainServlet,首先声明
Java代码 复制代码  收藏代码
  1. Map<String,Object[]> paramMap = request.getParameterMap();   
  2.   
  3. //此map对象用来缓存单页面的目标注入对象,比如此页面有多个Userinfo的属性需要注入,不可能每次注入都要生成Userinfo对象,肯定得在同一个对象中注入(小细节)   
  4. Map<String, Object> fieldMap = new HashMap<String, Object>();   
  5.   
  6. 得到请求信息后进行迭代   
  7. Set<Entry<String,Object[]>> paramSet = paramMap.entrySet();   
  8. for (Entry<String,Object[]> ent : paramSet) {   
  9.                    String paramName = (String) ent.getKey();   
  10.                       
  11.                    Object[] paramValue = ent.getValue();   
  12.                       
  13.                    handField(fieldMap,paramName,paramValue,action);   
  14. }  
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方法用来处理注入功能。
方法体和详细注释如下:
Java代码 复制代码  收藏代码
  1. //.这个字符是不能直接用正则的,需要转义   
  2.           String[] paramVos = paramName.split("\\.");   
  3.           //这里只支持 对象.属性的表单注入,对于多级的大家可以自行实现,相信不是难事儿。   
  4.            if (paramVos. length == 2) {   
  5.               Class actionClass = action.getClass();   
  6.               Object fieldObj = fieldMap.get(paramVos[0]);   
  7.               //从你的action得到目标注入对象   
  8.               Field field  = actionClass.getDeclaredField(paramVos[0]);;   
  9.                if (fieldObj == null) {   
  10.                    //假如是第一次注入,为空,则实例化目标对象   
  11.                    Class fieldClass = field.getType();   
  12.                    fieldObj = fieldClass.newInstance();   
  13.                    //放入缓存,第二次直接从缓存取,保证同一个form注入的是同一个对象    
  14.                    fieldMap.put(paramVos[0], fieldObj);   
  15.             }   
  16.               //构造目标属性的set方法    
  17.               String setMethod = "set"  
  18.                         + paramVos[1].substring(01).toUpperCase()   
  19.                         + paramVos[1].substring(1);   
  20.               Field fieldField = null;   
  21.               fieldField = fieldObj.getClass().getDeclaredField(   
  22.                         paramVos[1]);   
  23.   
  24.                  
  25.                if(realValue!= null){   
  26.                    InvocakeHelp. invokeMethod(fieldObj, setMethod,   
  27.                               new Object[] { paramValue });    
  28.               }   
  29.                  
  30.   
  31.           }  
//.这个字符是不能直接用正则的,需要转义
          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 }); 
              }
              

          }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值