一起写框架-MVC框架-基础功能-ServletAPI的动态绑定(五)

实现功能

以上的代码实现了通过路径执行对应的执行方法,但执行方法的参数是必须需要传入请求后响应的参数的。

分别为:HttpServletRequestHttpServletResponse。然后通过这个两个对象获得参数和处理参数。

需求:我们希望根据方法声明的参数列表决定是否需要ServletAPI的对象

  1. HttpServletRequest
  2. HttpServletResponse
  3. HttpSession
  4. ServletContext

而不是固定必须HttpServletRequest和HttpServletResponse。

 

实现思路

通过反射技术获得执行方法的参数列表。判断需要传入的ServletAPI对象。

 

实现步骤

1.在ControllerRelolver类中增加一个判断执行方法的参数列表方法 getparameterObjects

 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项目的目录结构

2.修改测试的UserController的执行方法,有多个ServletAPI的参数

 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.测试结果,输出对应的对象。成功!

 

posted @ 2017-11-12 00:05  继续前向  阅读(454)  评论(0编辑  收藏  举报