<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          手擼一個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
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丁香五月天激情在线 | 波多野结衣无码电影 | 欧美一级A片免费播放 | 美女操B 三级无码 | 日本在线欧美 |