[java反射]实现SpringMVC参数接收封装效果

看懂本文前提

  • 需要一点点的java基础
  • 需要一点点反射基础
  • 没有了

先大概讲讲废话,代码是当初学反射的时候自己想的示例,有些请求地址与方法间的映射判断忽略,在代码里写死了.
SpringMVC在启动的时候扫描注解,将Mapping于方法统一维护起来,在请求的时候通过路径匹配选择调用方法. Spring中可以通过下面代码查看所有请求接口及对应方法

   @Autowired
   private ApplicationContext applicationContext;
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
    mapping.getHandlerMethods();// 接口路径--方法的关系

不说废话了,看码…
之前学习时候的工程已经起不来了,把关键代码贴了出来,

  • 仿的被Spring管理的Conller 类
public class Kk {
    /**
     * 仿的Conller 方法
     * @param user
     * @param page
     */
    public void test(PracticeUser user, Page page) {
        System.out.println(user);
        System.out.println(page);
    }
}
  • URL接口类
// 一些于当前功能没关系的都上了
@GetMapping("/getPracticeUserList.ht")
    @ResponseBody
    public LayuiTabltBody getPracticeUserList(HttpServletRequest request , HttpServletResponse response, Page page) {
        //模仿实现参数接受
        //方法所在的类,框架内根据参数可以获取到
        Class<Kk> aClass = Kk.class;
        //对应的方法名
        String methodName = "test";
        try {
            kkUtli.test1(aClass, methodName,request,response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

仿写Spring处理类


@Component
public class KkUtli {

    /**
     * Class的test方法中的参数的属性只能是
     * java.lang.Integer
     * java.lang.Long
     * java.util.Date  ( "yyyy-MM-dd" AND "yyyy-MM-dd HH:mm:ss" )
     * java.lang.String
     * 四种类型
     * 参数不支持 无无参构造方法的数据类型
     *
     * @param Class
     * @param methodName
     * @param request
     * @param response
     * @throws Exception
     */
    public  void test1(Class Class, String methodName, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        //获取参数列表
        Map<String, String[]> parameterMap = request.getParameterMap();
        Set<String> keySet = parameterMap.keySet();
        //获取某个方法
        Method method = null;
        Method[] declaredMethods = Class.getDeclaredMethods();
        for (Method m : declaredMethods) {
            if (m.getName().equals(methodName)) {
                method = m;
                break;
            }
        }
        //获取对象类实例
        Object object = Class.newInstance();
//        ObjectMapper mapper = new ObjectMapper();
//         mapper.convertValue(object, Class);

        //获取这个方法的参数列表
        java.lang.Class<?>[] parameterTypes = method.getParameterTypes();
        // 用来存实例化好的参数
        List list = new ArrayList();
        // 便利参数列表
        for (Class c : parameterTypes) {
            //实例化参数
            Object o = c.newInstance();
            //获取参数列表
            Field[] fields = c.getDeclaredFields();
            //参数名字链表
            Set<String> stringSet = new HashSet<>();
            for (Field field : fields) {
                stringSet.add(field.getName());
            }
            //获取交集
            stringSet.retainAll(keySet);
            //遍历交集 表示该参数中的实体中有字段在参数中需要封装存在
            for (String name : stringSet) {
                Method[] methods = c.getDeclaredMethods();
                for (Method m : methods) {
                    if (("set" + upperCase(name)).equals(m.getName())) {
                        java.lang.Class<?> types = m.getParameterTypes()[0];
                        Method setPage = c.getMethod("set" + upperCase(name), types);
                        setPage.invoke(o, getArg(parameterMap, name, types));
                        break;
                    }
                }
            }

            //放入list中
            list.add(o);
        }
        //转换格式
        Object[] objects = list.toArray();
        method.invoke(object, objects);
    }

    /**
     * 首字母大写转换
     *
     * @param str
     * @return
     */
    public static String upperCase(String str) {
        char[] ch = str.toCharArray();
        if (ch[0] >= 'a' && ch[0] <= 'z') {
            ch[0] = (char) (ch[0] - 32);
        }
        return new String(ch);
    }

    public static Object getArg(Map<String, String[]> parameterMap, String name, Class<?> types) throws Exception {

        String s = parameterMap.get(name)[0];
        Object re;
        switch (types.getName()) {
            case "java.lang.Integer":
                re = Integer.valueOf(s);
                break;
            case "java.lang.Long":
                re = Long.valueOf(s);
                break;
            case "java.util.Date":
                java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd");
                if (s.length() != 10) {
                    java.text.SimpleDateFormat fat= new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date date = fat.parse(s);
                    s = formatter.format(date);
                }
                re = formatter.parse(s);
                break;
            default:
                re = s;
        }
        return re;
    }
}

代码都贴完了,现在讲下思路好了,

通过反射获得方法的参数列表,于请求中的参数列表进行匹配,如果相匹配则通过反射写入,
当所有参数列表都判断完成后,通过反射调用指定方法.
访问连接 后即可将参数分钟值对应的实体类中

http://localhost:8888/user/super/getPracticeUserList.ht?page=88&limit=2&account=%E8%B4%A6%E5%8F%B7
在这里插入图片描述
控制台打印效果
在这里插入图片描述
代码中 变量命名不是很规范懒得改都,都是以前学习时候写的,不过注释都齐全,希望对感兴趣的人有所帮助!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值