• 自定义MVC原理


    目录

    一、自定义MVC简介

    二、最初的增删改查

    三、反射版的增删改查

    四、自定义MVC工作原理图以及后台代码实现解析


    一、自定义MVC简介


                1、自定义MVC的概念?

    MVC全称名是Model(模型层) View(视图层) controller(控制层),它们分工明确,各司其职,同时也具有高类聚,低耦合的特点。


                 2、自定义MVC的作用?

                            节省时间和代码。

    比如说:我们在写一个项目时,都是从无到有的,创建的过程要写好多代码,还要花费好多时间。所以我们会写一个MVC来继承它,从而得到通用的效果,以至于有更多的时间与精力去完成自己的项目。


                  3、为什么会有自定义MVC?

    当我们自己项目要去写这么多servlet以及dao包中的方法时,往往都会出现一个共同的问题,那就是代码思路基本重复,从而就诞生了自定义MVC。

    二、最初的增删改查

    我们以书本的增删改查为例,先回顾一下最初是怎样部署代码的:

    demo1.jsp代码:

     然后建增删改查的servlet:

     我们分别在增删改查的servlet里面写一些内容:

     然后我们运行demo1.jsp界面,得到如下效果:

     接着分别点击增加、删除、修改、查询的按钮,打印结果如下:

     以上就是我们最初的增删改查,那么会存在哪些问题呢?

              ①关于单个实体/表 操作场景越多,需要新建的类也就越多,造成了项目中类的数量过于庞大。

              对于这个问题,我们要优化,

    三、反射版的增删改查

    新建一个 BookServlet

    1. package com.ycx.web;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.annotation.WebServlet;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. @WebServlet("/book.action")
    9. public class BookServlet extends HttpServlet{
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. doPost(req, resp);
    13. }
    14. @Override
    15. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    16. // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
    17. String methodName = req.getParameter("methodName");
    18. if("add".equals(methodName)) {
    19. // 如果前台传递到后台的是一个新增的请求,那么后台就新增方法
    20. add(req,resp);
    21. }else if("del".equals(methodName)){
    22. del(req,resp);
    23. }else if("edit".equals(methodName)){
    24. edit(req,resp);
    25. }else if("list".equals(methodName)){
    26. list(req,resp);
    27. }
    28. }
    29. private void list(HttpServletRequest req, HttpServletResponse resp) {
    30. System.out.println("在同一个servlet中调用 list 方法");
    31. }
    32. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    33. System.out.println("在同一个servlet中调用 edit 方法");
    34. }
    35. private void del(HttpServletRequest req, HttpServletResponse resp) {
    36. System.out.println("在同一个servlet中调用 del 方法");
    37. }
    38. private void add(HttpServletRequest req, HttpServletResponse resp) {
    39. System.out.println("在同一个servlet中调用 add 方法");
    40. }
    41. }

     然后在demo1.jsp:

    1. <h3>类数量过多问题的优化</h3>
    2. <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
    3. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    4. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    5. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>

    控制台运行结果:

    那么又遇到另一个问题:

     ②当增加了业务,除了要添加该业务对应的方法(load),同时还要改动原有的代码

    优化BookServlet

    1. @Override
    2. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    3. // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
    4. String methodName = req.getParameter("methodName");
    5. // methodName可能是多种方法
    6. // 前台传递什么方法就调用当前类的对应方法
    7. try {
    8. Method m=this.getClass()// BookServlet.Class
    9. .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    10. m.setAccessible(true);
    11. // 调用当前类实例的 methodName 方法
    12. m.invoke(this, req,resp);
    13. } catch (Exception e) {
    14. e.printStackTrace();
    15. }
    16. private void load(HttpServletRequest req, HttpServletResponse resp) {
    17. System.out.println("在同一个servlet中调用 load 方法");
    18. }

     在demo1.jsp界面再添加一个回显按钮:

    <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>

     控制台运行结果如下:

     好,如果我们再写一个订单类的增删改查:

     一样也可以调用到:

     

     但是又会存在什么问题呢?

    注意看:

    所以面临第三、四个问题:

            ③ 反射相关代码,在每一个实体类对应的servlet中都存在

            ④每一个servlet中都有doget和dopost方法

    所以接下来本节重点来啦!!!

    四、自定义MVC工作原理图以及后台代码实现解析

    我们接下来按照这个原理图去部署代码:

    新建一个com.ycx.framework

    DispatcherServlet:

    1. package com.ycx.framework;
    2. import java.io.IOException;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. import javax.servlet.ServletException;
    6. import javax.servlet.annotation.WebServlet;
    7. import javax.servlet.http.HttpServlet;
    8. import javax.servlet.http.HttpServletRequest;
    9. import javax.servlet.http.HttpServletResponse;
    10. import com.ycx.web.BookAction;
    11. /**
    12. * 中央控制器:
    13. * 主要职能:接收浏览器请求,找到对应的处理人
    14. * @author 杨总
    15. *
    16. */
    17. @WebServlet("*.action")
    18. public class DispatcherServlet extends HttpServlet{
    19. private Map<String, Action> actions=new HashMap<String, Action>();
    20. // 程序启动时,只会加载一次
    21. @Override
    22. public void init() throws ServletException {
    23. actions.put("/book", new BookAction());
    24. // actions.put("/order", new BookAction());
    25. }
    26. @Override
    27. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    28. doPost(req, resp);
    29. }
    30. @Override
    31. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    32. //http:localhost:8080/mvc/book.action?methodName=list
    33. String uri=req.getRequestURI();
    34. // 拿到/book,就是最后一个“/”到最后一个“.”为止
    35. uri=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
    36. Action action = actions.get(uri);
    37. action.execute(req, resp);
    38. }
    39. }

     注意:其中有一个初始化init方法:

     

     

     就生成了一个init初始化方法:

    ActionSupport:

    1. package com.ycx.framework;
    2. import java.lang.reflect.Method;
    3. import javax.servlet.http.HttpServletRequest;
    4. import javax.servlet.http.HttpServletResponse;
    5. public class ActionSupport implements Action{
    6. @Override
    7. public void execute(HttpServletRequest req, HttpServletResponse resp) {
    8. String methodName = req.getParameter("methodName");
    9. // methodName可能是多种方法
    10. // 前台传递什么方法就调用当前类的对应方法
    11. try {
    12. Method m=this.getClass()// BookServlet.Class
    13. .getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    14. m.setAccessible(true);
    15. // 调用当前类实例的 methodName 方法
    16. m.invoke(this, req,resp);
    17. } catch (Exception e) {
    18. e.printStackTrace();
    19. }
    20. }
    21. }

    Action:

    1. package com.ycx.framework;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. /**
    7. * 子控制器:
    8. * 对应请求的处理人
    9. * @author 杨总
    10. *
    11. */
    12. public interface Action {
    13. void execute(HttpServletRequest req, HttpServletResponse resp);
    14. }

    com.ycx.web包内添加一个BookAction类:

    BookAction:

    1. package com.ycx.web;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import com.ycx.framework.Action;
    5. import com.ycx.framework.ActionSupport;
    6. public class BookAction extends ActionSupport {
    7. private void load(HttpServletRequest req, HttpServletResponse resp) {
    8. System.out.println("在同一个servlet中调用 load 方法");
    9. }
    10. private void list(HttpServletRequest req, HttpServletResponse resp) {
    11. System.out.println("在同一个servlet中调用 list 方法");
    12. }
    13. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    14. System.out.println("在同一个servlet中调用 edit 方法");
    15. }
    16. private void del(HttpServletRequest req, HttpServletResponse resp) {
    17. System.out.println("在同一个servlet中调用 del 方法");
    18. }
    19. private void add(HttpServletRequest req, HttpServletResponse resp) {
    20. System.out.println("在同一个servlet中调用 add 方法");
    21. }
    22. }

    部署完毕之后,我们开始运行

    比如点击书籍的删除增加按钮,控制台打印结果如下:

    我们的mvc原理就根据原理图以代码的形式呈现出来啦 ~

     今日分享就到这里啦~再会!

  • 相关阅读:
    聊聊JDK1.0到JDK20的那些事儿
    Java多线程:Thread类常用API
    SpringCloud-Eureka快速入门,集群搭建
    异步FIFO
    Anaconda彻底卸载及重安装
    IDEA 打开项目后看不到项目结构怎么办?
    php如何解决高并发问题
    Qt/C++音视频开发54-视频监控控件的极致设计
    java计算机毕业设计社交的健身网课平台服务器端源码+系统+数据库+lw文档+mybatis+运行部署
    数据结构排序算法之直接插入排序与希尔排序【图文详解】
  • 原文地址:https://blog.csdn.net/weixin_65808248/article/details/125449863