1. 程式人生 > >一起寫框架-MVC框架-基礎功能-ServletAPI的動態綁定(五)

一起寫框架-MVC框架-基礎功能-ServletAPI的動態綁定(五)

lol gen let session host 測試web mvc https contex

實現功能

以上的代碼實現了通過路徑執行對應的執行方法,但執行方法的參數是必須需要傳入請求後響應的參數的。

分別為: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.測試結果,輸出對應的對象。成功!

技術分享

一起寫框架-MVC框架-基礎功能-ServletAPI的動態綁定(五)