1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        手擼一個mvc框架有多簡單

        共 7981字,需瀏覽 16分鐘

         ·

        2021-09-13 03:07

        在web配置類中定義一個處理前端請求的servlet


        web.xml 配置

        <?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"         version="4.0"><!--    定義一個集中處理前端請求的servlet-->    <servlet>        <servlet-name>DispatcherServlet</servlet-name>        <servlet-class>com.zhou.mvc.DispatcherServlet</servlet-class><!--        定義初始化參數 用于解析配置文件中的類信息-->        <init-param>            <param-name>contentConfigLocation</param-name>            <param-value>application.properties</param-value>        </init-param><!--        服務器一啟動此類就加載-->        <load-on-startup>0</load-on-startup>    </servlet>    <servlet-mapping><!--        所有帶有.do結尾的請求都被映射到此類中-->        <servlet-name>DispatcherServlet</servlet-name>        <url-pattern>*.do</url-pattern>    </servlet-mapping></web-app>



        DispatcherServlet 類

        package com.zhou.mvc;

        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;

        public class DispatcherServlet extends HttpServlet { //初始化方法 利用反射機制事先把類以及方法進行預處理 @Override public void init(ServletConfig config) throws ServletException { //讀取配置文件路徑 String path = config.getInitParameter("contentConfigLocation"); //配置文件內容轉換為輸入流 InputStream is = DispatcherServlet.class.getClassLoader().getResourceAsStream(path); //把配置文件的輸入流傳入此處理器 利用反射機制事先把配置文件中指定的類以及方法進行預處理 HandleMapping.load(is); }

        @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.獲取用戶請求的uri String uri = req.getRequestURI(); HandleMapping.MVCMapping mapping = HandleMapping.get(uri); if(mapping==null){ resp.sendError(404,"自定義MVC:映射地址不存在"+uri); return; } Object obj = mapping.getObj(); Method method = mapping.getMethod(); String result = null; try { //利用反射直接調用此方法并且獲得此方法的返回值 result = (String) method.invoke(obj, req, resp); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } switch (mapping.getType()){ case TEXT: //如果是純文本就利用打印流直接寫回前端頁面 resp.getWriter().write(result); break; case VIEW: //如果是視圖 就直接進行重定向 resp.sendRedirect(result); break; } }}



        HandleMapping 類


        package com.zhou.mvc;

        import java.io.IOException;import java.io.InputStream;import java.lang.annotation.Annotation;import java.lang.reflect.Method;import java.util.Collection;import java.util.HashMap;import java.util.Map;import java.util.Properties;

        /** * 映射器(包含了大量的網址與方法的對應關系),封裝了一個每一個uri所對應的映射對象 */public class HandleMapping { //key為uri 值為映射對象 private static Map<String, MVCMapping> data = new HashMap<>(); public static MVCMapping get(String uri){ return data.get(uri); } public static void load(InputStream is) {// 定義存儲配置文件中的類信息的集合 Properties ppt = new Properties(); try { //裝載后的數據結構與hashMap類似 key為配置文件的=左,值為=右(類路徑) ppt.load(is); } catch (IOException e) { e.printStackTrace(); } //獲得所有類路徑的集合 Collection<Object> values = ppt.values(); //遍歷每一個類的項目路徑 for (Object cla : values) { String claasName = (String) cla; try { //加載配置文件中描述的每一個類 Class c = Class.forName(claasName); //創(chuàng)建這個類的對象 Object o = c.getConstructor().newInstance(); //獲取這個類的所有方法 Method[] methods = c.getMethods(); //遍歷所有方法 for (Method m : methods) { //得到此方法上的所有注解 Annotation[] as = m.getAnnotations(); if (as != null) { for (Annotation a : as) { if (a instanceof ResponseBody) { //說明此方法用于返回字符串給客戶端 MVCMapping mapping = new MVCMapping(o,m,ResponseType.TEXT); //key為uri 值為映射對象 MVCMapping put = data.put(((ResponseBody) a).value(), mapping); if (put != null){ //存在了重復的請求地址 throw new RuntimeException("請求地址重復"+((ResponseBody) a).value()); } } else if (a instanceof ResponseView) { //說明此方法,用于返回界面給客戶端 MVCMapping mapping = new MVCMapping(o,m,ResponseType.VIEW); MVCMapping put = data.put(((ResponseView) a).value(), mapping); if (put != null){ //存在了重復的請求地址 throw new RuntimeException("請求地址重復"+((ResponseView) a).value()); } } } } } } catch (Exception e) { e.printStackTrace(); } } }

        /** * 映射對象,每一個對象封裝了一個方法,用于處理請求 */ public static class MVCMapping { private Object obj; private Method method; private ResponseType type;

        public MVCMapping() { }

        public MVCMapping(Object obj, Method method, ResponseType type) { this.obj = obj; this.method = method; this.type = type; }

        public Object getObj() { return obj; }

        public void setObj(Object obj) { this.obj = obj; }

        public Method getMethod() { return method; }

        public void setMethod(Method method) { this.method = method; }

        public ResponseType getType() { return type; }

        public void setType(ResponseType type) { this.type = type; } }}



        ResponseBody 和 ResponseView 注解類


        package com.zhou.mvc;

        import java.lang.annotation.*;

        @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documented/** * 被此注解添加的方法,會被用于處理請求 * 方法返回的內容,以文字形式返回到客戶端 */public @interface ResponseBody { String value();}


        package com.zhou.mvc;

        import java.lang.annotation.*;

        @Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documented/** * 被此注解添加的方法,會被用于處理請求 * 方法返回的內容,會直接重定向 */public @interface ResponseView { String value();}



        ResponseType 枚舉類


        package com.zhou.mvc;

        public enum ResponseType { TEXT,VIEW;}



        測試控制類:


        package com.zhou.gc.test2.test;

        import com.zhou.mvc.ResponseBody;import com.zhou.mvc.ResponseView;

        import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

        public class UserController { @ResponseBody("/testLogin.do") public String login(HttpServletRequest req, HttpServletResponse resp) {

        return "login success";

        } @ResponseView("/reg.do") public String reg(HttpServletRequest req, HttpServletResponse resp){ return "success.jsp"; }}



        把測試類添加到配置文件 application.properties


        #在這里配置用于處理請求的類,每一個類中可能包含0到n個處理請求的方法a = com.zhou.gc.test2.test.UserController


        測試頁面:



        作者:JuiRing

        鏈接:https://blog.csdn.net/LLLlucky_boy/article/details/120122147


        瀏覽 27
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品久久久久久久久久白浆 | 国产理论片一区二区三区在线观看 | 日本黄色免费 | 日本丰满少妇bbbbbb黑人 | 黄色直播网址 | 爱草在线| 大BBBBB小BBBBBB | 四虎午夜影院 | 青草福利 | 男女A级毛视频免费观看 |