@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {if (methodMap.isEmpty()){return;}String uri = req.getRequestURI();String contextPath = req.getContextPath();//獲取有效urlString url = uri.replace(contextPath,"");//如果沒有對(duì)應(yīng)的url,返回404if (!methodMap.containsKey(url)){resp.getWriter().println("404");}else {//有的話,通過invoke方法執(zhí)行對(duì)應(yīng)controller的methodMethod method = methodMap.get(url);Object controller = controllerMap.get(url);try {method.invoke(controller);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}至此,MyDispatcherServlet的所有代碼都已經(jīng)完成了,他也能夠成為一個(gè)合格的領(lǐng)導(dǎo)了 。
上面部分代碼寫的較為分散,文末放上MyDispatcherServlet的完整代碼供同學(xué)們參考
最后,編寫一個(gè)Controller進(jìn)行測(cè)試package com.cloudwise.controller;/*** @author Teacher 陳* @creat 2021-02-22-14:57* @describ*/import com.cloudwise.annotition.MyController;import com.cloudwise.annotition.MyRequestMapping;/*** @author :Teacher 陳* @date :Created in 2021/2/22 14:57* @description:我的實(shí)驗(yàn)性Controller* @modified By:* @version:*/@MyController@MyRequestMapping(value = "https://www.520longzhigu.com/test")public class MyFirstController {@MyRequestMapping(value = "https://www.520longzhigu.com/test1")public void test1(){System.out.println("test1被調(diào)用了");}@MyRequestMapping(value = "https://www.520longzhigu.com/test2")public void test2(){System.out.println("test2被調(diào)用了");}@MyRequestMapping(value = "https://www.520longzhigu.com/test3")public void test3(){System.out.println("test3被調(diào)用了");}}測(cè)試1.為本項(xiàng)目配置tomcat
2.運(yùn)行
3.1瀏覽器地址欄輸入對(duì)應(yīng)網(wǎng)址
控制臺(tái)成功打印日志信息
3.2瀏覽器地址欄輸入無效網(wǎng)址,頁面返回404
至此,今天的手寫springMVC就全部完成了 。
當(dāng)然本項(xiàng)目還有很多待提升的地方,諸如不能返回json數(shù)據(jù),controller不能有參數(shù),等等 。但是我們不可能一朝一夕建成羅馬,應(yīng)該一步一個(gè)腳印,通過這個(gè)項(xiàng)目掌握springMVC的運(yùn)行流程,為以后更難的項(xiàng)目打下點(diǎn)基礎(chǔ) 。
代碼(總覽)package com.cloudwise.servlet;/*** @author Teacher 陳* @creat 2021-02-22-13:44* @describ*/import com.cloudwise.annotition.MyController;import com.cloudwise.annotition.MyRequestMapping;import org.reflections.Reflections;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.*;/*** @author :Teacher 陳* @date :Created in 2021/2/22 13:44* @description:我的前端控制器dispather* @modified By:* @version:*/public class MyDispatcherServlet extends HttpServlet {/*** 我們將需要掃描的包放在一個(gè).properties文件中* 需要在初始化的時(shí)候讀取它*/private Properties properties = new Properties();/*** 我們需要一個(gè)Set,將所有能夠響應(yīng)的Controller存起來*/private Set<Class<?>> classSet = new HashSet<>();/*** 類spring-mvc容器,存儲(chǔ)Controller對(duì)象*/private Map<String,Object> mySpringMVCContext = new HashMap<>();/*** 存儲(chǔ)所有方法的Map<url:method>*/private Map<String,Method> methodMap = new HashMap<>();/*** 存儲(chǔ)所有Controller的Map*/private Map<String,Object> controllerMap = new HashMap<>();/*** @description: 初始化,要做什么事呢?* 0. 接收到請(qǐng)求之后,首先將后端環(huán)境初始化好* 1. 加載配置文件* 2. 掃描controller包* 3. 初始化controller* 4. 初始化Controller映射器* @create by: Teacher 陳* @create time: 2021/2/22 13:47* @param config* @return void*/@Overridepublic void init(ServletConfig config) throws ServletException {//1. 加載配置文件String initParameter = config.getInitParameter("contextConfigLocation");try {loadConfigfile(initParameter);} catch (IOException e) {e.printStackTrace();}//2. 掃描controller包,存儲(chǔ)所有能夠響應(yīng)的ControllerscanPackage(properties.getProperty("package"));//3. 初始化controllertry {initController();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}//4. 初始化Controller映射器initHandlerMapping();}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {if (methodMap.isEmpty()){return;}String uri = req.getRequestURI();String contextPath = req.getContextPath();String url = uri.replace(contextPath,"");if (!methodMap.containsKey(url)){resp.getWriter().println("404");}else {Method method = methodMap.get(url);Object controller = controllerMap.get(url);try {method.invoke(controller);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}/*** 以下為工具性函數(shù)*//*** 加載配置文件* @param fileName*/private void loadConfigfile(String fileName) throws IOException {//以流的方式獲取資源InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(fileName);properties.load(resourceAsStream);resourceAsStream.close();}/*** 掃描包,獲取所有帶MyController的類* @param packageName*/private void scanPackage(String packageName){Reflections reflections = new Reflections(packageName);classSet = reflections.getTypesAnnotatedWith(MyController.class);}/*** 初始化Controller*/private void initController() throws IllegalAccessException, InstantiationException {if(classSet.isEmpty()){return;}for (Class<?> controller : classSet) {mySpringMVCContext.put(firstWordToLowCase(controller.getSimpleName()),controller.newInstance());}}/*** 首字母轉(zhuǎn)小寫* @param string* @return 首字母為小寫的String*/private String firstWordToLowCase(String string){char[] chars = string.toCharArray();//將大寫轉(zhuǎn)成小寫chars[0]+=32;return String.valueOf(chars);}private void initHandlerMapping() {if (mySpringMVCContext.isEmpty()){return;}for (Map.Entry<String, Object> entry : mySpringMVCContext.entrySet()) {Class<?> entryClass = entry.getValue().getClass();if (!entryClass.isAnnotationPresent(MyController.class)){continue;}//Controller類上的requestMapping值,如果有則獲取String baseUrl = "";if (entryClass.isAnnotationPresent(MyRequestMapping.class)){MyRequestMapping annotation = entryClass.getAnnotation(MyRequestMapping.class);baseUrl = annotation.value();}//獲取所有方法Method[] methods = entryClass.getMethods();for (Method method : methods) {if (method.isAnnotationPresent(MyRequestMapping.class)){MyRequestMapping annotation = method.getAnnotation(MyRequestMapping.class);String url = annotation.value();url = baseUrl + url;//將該方法放入方法集methodMap.put(url,method);//將該controller方法處理器集controllerMap.put(url,entry.getValue());//至此,初始化完成,后端整裝待發(fā)}}}}}
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專業(yè)人士給予相關(guān)指導(dǎo)!
「愛刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助:- 出新的治理框架 阿富汗總統(tǒng)加尼弟弟宣誓效忠塔利班
- 網(wǎng)頁前端開發(fā) 前端快速開發(fā)框架有哪些
- 詳解ajax框架作用 ajax框架教程
- 簡(jiǎn)單快速構(gòu)建后臺(tái)管理系統(tǒng) 后臺(tái)模板框架的模板
- struts2和springMVC的區(qū)別 struts2配置文件詳解
- 十個(gè)前端UI優(yōu)秀框架 前端ui框架有哪些
- 基于ssm框架的圖書管理系統(tǒng) 網(wǎng)站框架模板代碼
- 單點(diǎn)登錄失敗解決措施 單點(diǎn)登錄框架有哪些
- java開發(fā)常用的框架 java框架都有哪些
- 免費(fèi)google賬號(hào)注冊(cè) google服務(wù)框架安裝
