优雅实现request请求IOC

来源:互联网 发布:一七网络批发广州 编辑:程序博客网 时间:2024/06/07 07:19

前言

上篇我们谈到了如何通过过滤器去分发请求,实现了请求servlet的特定方法的问题,那么携带的参数如何转化为我们想要的javaBean呢?今天就探讨一下该问题该如何解决。

期望

URL:http://localhost:8080/webstu/action/cookie/cookie.do!test?name=yzz&password=123
通过该URL访问cookie.do所映射的servlet的test方法,通过name和password实例化该参数。

结果:

这里写图片描述

实现

创建基类BaseAction

该基类继承了HttpServlet,实现的是service方法。在service方法中,只做一件事情,就是invoke请求的方法

首先是要讲请求的action中所有的方法全部读出来,以静态变量的形式保存。

//这里的参数,要求是1个以内,多个的,处理方式将不一样,这里不做考虑,所有的请求的参数都将被视为是一个bean。 private void initMap(){        methodMap = new HashMap<>();        Method[] methods = this.getClass().getDeclaredMethods();        for (Method method:                methods) {            method.setAccessible(true);            Class[] c = method.getParameterTypes();            //参数为1就讲method对象加进map中            if (c.length==1){                methodMap.put(method.getName(),method);            }            //没有参数就置空            if (c.length==0){                methodMap.put(method.getName(),null);            }        }        Log.e(methodMap.toString());    }
 @Override    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        if (methodMap==null)initMap();        Log.e(Utils.getTime()+"BaseAction:service");        this.req = req;        this.resp = resp;        String method = (String) req.getAttribute("method");        try {            Log.e(""+method);            if (methodMap.get(method) == null)            //没有参数的方法                this.getClass().getMethod(method).invoke(this);            else {            //有参数的方法,将通过ReflectUtil工具类来实例化参数,再去invoke                Class tclass = methodMap.get(method).getParameterTypes()[0];                Object arg = ReflectUtil.initObj(tclass,req.getParameterMap());                methodMap.get(method).invoke(this, arg);            }        } catch (Exception e) {            e.printStackTrace();        }    }

ReflectUtil工具类

package com.yzz.java.util.ioc;import java.util.ArrayList;import java.util.List;import java.util.Map;/** * Created by yzz on 2017/9/17. * mail:yzzstyle@163.com */public class ReflectUtil {    public static <T>  T initObj(Class<T> tClass,Map<String,String[]> map){        T t = null;        try {            //创建对象实例            t = tClass.newInstance();            //赋值操作            for (Map.Entry<String,String[]> en:map.entrySet()) {                invoke(t,en.getKey(),en.getValue());            }        } catch (Exception e) {            e.printStackTrace();        }finally {            return t;        }    }//将request的参数,注入到bean中,实例化bean    public static <T> void invoke(T t,String name,String[] value) throws Exception{        String mehodName = getMethodName(name);        if (value.length>1){            List<String> list = new ArrayList();            for (String s:                 value) {                list.add(s);            }            t.getClass().getMethod(mehodName,list.getClass()).invoke(t,list);        }else if (value.length==1){            Object p = value[0];            t.getClass().getMethod(mehodName,p.getClass()).invoke(t,p);        }else {            t.getClass().getMethod(mehodName,String.class).invoke(t,"undefined");        }    }//字符创转化成 setName的形式    public static String getMethodName(String name){        String uper = name.substring(0,1).toUpperCase();        String set = "set";        String end = name.substring(1,name.length());        return set+uper+end;    }}

总结

这里的Action必须是BaseAction的子类,也必须到xml上注册,当然也可以使用注解的方式来去做,满足这些条件后,通过访问上面的url将会返回实例化后的bean。

原创粉丝点击