spring mvc框架源码分析(三)-执行请求路径所对应方法并返回

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

之前第一节我们讲了DispatchServlet中会对请求做一些处理,这些处理即是执行请求路径所对应的方法。

获取此请求路径所对应的方法:

通过这两个方法获取了请求路径以及请求方式

     String url = servletRequest.getRequestURI();
     String method = servletRequest.getMethod();

然后获取之前在AnnotionUtil方法中获取到的所有的路径和方法,并且找到当前请求路径所对应的字符串集

     List<String> list = (List<String>) getServletContext().getAttribute("annotationList"); String urlAndMethod = url + " " + method; String thisRequest = ""; for (String s : list) { if (s.contains(urlAndMethod)) { thisRequest = s; break; } }

获取到请求所对应的字符串集后,之后我们需要做的事情就是执行此路径所对应的方法。首先需要判断此路径是否对应有方法,没有的话返回错误页面,之后在路径所对应的字符串集中取出其类名和方法名,并且获取到方法中的参数的类型,最后执行路径所对应方法

      if (!thisRequest.equals("")) {
                String[] stringArray = thisRequest.split(" ");
                try {
                    Class<?> cla = Class.forName(stringArray[3]);
                    Method[] methods = cla.getMethods();
                    Class<?>[] classes = null;
                    for (Method method1 : methods) {
                        if (method1.getName().equals(stringArray[4])) { //获取参数类型
                            Class<?>[] parameterTypes = method1.getParameterTypes();
                            for (int i = 0; i < parameterTypes.length; i++) {
                                classes = parameterTypes;
                            }

                        }
                    }
                    Object o = cla.newInstance(); //实例化当前类
                    Object[] objects = getParam(classes);赋予参数值
                    String result = (String) cla.getMethod(stringArray[4], classes).invoke(o,objects);//反射执行方法并接受返回结果
                    if (stringArray[2].equals(SystemConfig.ResponsePage)) {//处理返回结果
                        servletRequest.getRequestDispatcher("/" + result).forward(servletRequest, servletResponse);
                    } else {
                        servletResponse.getWriter().write(result);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                servletResponse.getWriter().write("error");
            }
        public Object[] getParam(Class<?>[] classes) {
            Object[] objects = null;
            if (classes!=null){
                objects= new Object[classes.length];
    //因为目前参数只支持httpServletRequest和httpServletResponse,后续会完善
            for (int i = 0;i<classes.length;i++){
                if (classes[i].getName().contains("HttpServletRequest")){
                    objects[i] = httpServletRequest;
                }else if (classes[i].getName().contains("HttpServletRequest")) {
                    objects[i] = httpServletResponse;
                }else {
                    objects[i] = null;
                }

            }
            }
            return objects;
        }

DispatchServlet:

    public class DispatcherServlet extends GenericServlet implements Serializable{

        private HttpServletRequest httpServletRequest = null;
        private HttpServletResponse httpServletResponse = null;

        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request = (HttpServletRequest)servletRequest;
                response = (HttpServletResponse)servletResponse;
                httpServletRequest = request;
                httpServletResponse = response;
            }catch (Exception e){
                throw new ServletException("non-HTTP request or response");
            }
            this.service(request,response);
        }

        public void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException {
            String url = servletRequest.getRequestURI();
            String method = servletRequest.getMethod();
            List<String> list = (List<String>) getServletContext().getAttribute("annotationList");
            String urlAndMethod = url + " " + method;
            String thisRequest = "";

            for (String s : list) {
                if (s.contains(urlAndMethod)) {
                    thisRequest = s;
                    break;
                }
            }
            if (!thisRequest.equals("")) {
                String[] stringArray = thisRequest.split(" ");
                try {
                    Class<?> cla = Class.forName(stringArray[3]);
                    Method[] methods = cla.getMethods();
                    Class<?>[] classes = null;
                    for (Method method1 : methods) {
                        if (method1.getName().equals(stringArray[4])) {
                            Class<?>[] parameterTypes = method1.getParameterTypes();
                            for (int i = 0; i < parameterTypes.length; i++) {
                                classes = parameterTypes;
                            }

                        }
                    }
                    Object o = cla.newInstance();
                    Object[] objects = getParam(classes);
                    String result = (String) cla.getMethod(stringArray[4], classes).invoke(o,objects);
                    if (stringArray[2].equals(SystemConfig.ResponsePage)) {
                        servletRequest.getRequestDispatcher("/" + result).forward(servletRequest, servletResponse);
                    } else {
                        servletResponse.getWriter().write(result);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                servletResponse.getWriter().write("error");
            }
        }

        public Object[] getParam(Class<?>[] classes) {
            Object[] objects = null;
            if (classes!=null){

                objects= new Object[classes.length];

            for (int i = 0;i<classes.length;i++){
                if (classes[i].getName().contains("HttpServletRequest")){
                    objects[i] = httpServletRequest;
                }else if (classes[i].getName().contains("HttpServletRequest")) {
                    objects[i] = httpServletResponse;
                }else {
                    objects[i] = null;
                }

            }
            }
            return objects;
        }
    }

测试:

      @MyRequestMapping(path = "/zhu/html_test",method = RequestMethod.GET)
        public String testOneaa(){
            return "xxx.html";
        }

20191102100826\_1.png

      @MyResponseString
        @MyRequestMapping(path = "/zhu/test1",method = RequestMethod.GET)
        public String testA(HttpServletRequest httpServletRequest){
            return "xx";
        }

20191102100826\_2.png

        @MyRequestMapping(path = "/zhu/test",method = RequestMethod.GET)
        public String testOne(){
            return "index.jsp";
        }

20191102100826\_3.png

总结:

最初的框架较简便,后期会完善它,讲到这大概就讲完了,很简单,只是实现了一些基本的功能还有很多细节没有处理,完整看看整个架构就运用了java的反射和注解,枚举,以及一些java web编程的基本知识,没有涉及到高深的东西,所以还是很好理解的。

项目源码地址:

http://pan.baidu.com/s/1i5sFPxr


来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring mvc框架源码分析(三)-执行请求路径所对应方法并返回

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏