實現功能 以上的代碼實現了通過路徑執行對應的執行方法,但執行方法的參數是必須需要傳入請求後響應的參數的。 分別為:HttpServletRequest和HttpServletResponse。然後通過這個兩個對象獲得參數和處理參數。 需求:我們希望根據方法聲明的參數列表決定是否需要ServletAP ...
實現功能
以上的代碼實現了通過路徑執行對應的執行方法,但執行方法的參數是必須需要傳入請求後響應的參數的。
分別為:HttpServletRequest和HttpServletResponse。然後通過這個兩個對象獲得參數和處理參數。
需求:我們希望根據方法聲明的參數列表決定是否需要ServletAPI的對象
- HttpServletRequest
- HttpServletResponse
- HttpSession
- 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.測試結果,輸出對應的對象。成功!