以上的代码实现了经过路径执行对应的执行方法,但执行方法的参数是必须须要传入请求后响应的参数的。web
分别为:HttpServletRequest和HttpServletResponse。而后经过这个两个对象得到参数和处理参数。数组
需求:咱们但愿根据方法声明的参数列表决定是否须要ServletAPI的对象session
而不是固定必须HttpServletRequest和HttpServletResponse。mvc
经过反射技术得到执行方法的参数列表。判断须要传入的ServletAPI对象。app
1.在ControllerRelolver类中增长一个判断执行方法的参数列表方法 getparameterObjectsjsp
1 private Object[] getparameterObjects(Parameter[] parameters) { 2 // 1.建立设置一个参数对象的数组,参数的格式和参数类型的个一致 3 Object[] parameterObjects = new Object[parameters.length]; 4 //2.根据参数的类型,将对于的对象填在对象数组中 5 for(int i=0;i<parameters.length;i++){ 6 Class<?> typeClass = parameters[i].getType(); 7 //3.根据判断方法参数的类型和咱们制定的4个做用是不是父子类关系。若是是就赋值 8 if(ServletRequest.class.isAssignableFrom(typeClass)){ 9 parameterObjects[i]=this.request; 10 }else if(ServletResponse.class.isAssignableFrom(typeClass)){ 11 parameterObjects[i]=this.response; 12 }else if(HttpSession.class.isAssignableFrom(typeClass)){ 13 parameterObjects[i]=this.session; 14 }else if(ServletContext.class.isAssignableFrom(typeClass)){ 15 parameterObjects[i]=this.application; 16 } 17 18 } 19 return parameterObjects; 20 }
2.修改ControllerRelolver的execute()方法,调用getparameterObjects方法来根据执行方法的参数列表,动态调用Controller的方法时传入对应的值测试
1 public String execute(HttpServletRequest request,HttpServletResponse response,Context context) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{ 2 //1.设置Servlet须要的API对象 3 this.request=request; 4 this.response=response; 5 this.session=request.getSession(); 6 this.application=request.getServletContext(); 7 8 //1.得到请求过来的路径 9 String uri = request.getRequestURI(); 10 //2.根据路径规则,得到映射路径 11 String path = this.pathRule(uri); 12 //3.经过路径得到容器中对应的业务控制器的对象和执行方法 13 MappingEnttiy mappingEnttiy = this.getRequestMethod(path, context); 14 //4.得到执行方法 15 Method method = mappingEnttiy.getMethod(); 16 //5.得到路径对应的业务控制器 17 Object controller = mappingEnttiy.getController(); 18 //6.执行方法,执行方法必须有request,response两个参数 19 Parameter[] parameters = method.getParameters(); 20 //7.给执行的方法,设置根据执行方法的参数赋予对应的ServletAPI对象 21 Object[] objects = this.getparameterObjects(parameters); 22 //8.动态调用方法,将参数对应的对象赋值执行方法 23 Object resultObject = method.invoke(controller, objects); 24 if(resultObject!=null){ 25 //7.返回执行方法返回的映射字符串 26 return (String) resultObject; 27 } 28 return null; 29 }
1.测试web项目的目录结构this
2.修改测试的UserController的执行方法,有多个ServletAPI的参数spa
1 /** 2 * 路径规则: 3 * 1.必须包括有/开头 4 * 2.后缀必须忽略不写 5 * 如:http://localhost:8080/webmvc-demo-test-01/test.do 6 * 对应的映射路径为:/test 7 * 8 */ 9 @RequestMapping(value = "/login") 10 public String login(HttpServletRequest request,HttpServletResponse response,ServletContext application,HttpSession session){ 11 System.out.println("-登陆Controller-"); 12 System.out.println(request); 13 System.out.println(response); 14 System.out.println(application); 15 System.out.println(session); 16 return "redirect:/login.jsp"; 17 18 }
3.测试结果,输出对应的对象。成功!code