• 自定义MVC原理


    目录

    一、什么是MVC?

    二、初版的增删改查

    三、类过多的优化

     四、反射优化

    五、MVC工作原理以及对应打码


    一、什么是MVC

    M:model
    V:view
    C:controller
    分工明确,各司其职
    降低代码耦合度

    二、初版的增删改查

    写一个Demo01.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>Insert title here</title>
    8. </head>
    9. <body>
    10. <h3>目前增删改查的方法</h3>
    11. <a href="${pageContext.request.contextPath }/book/add">增加</a>
    12. <a href="${pageContext.request.contextPath }/book/del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book/edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book/list">查询</a>
    15. <!--
    16. 上述问题:
    17. 1.关于单个实体/表操作场景越多,需要新建的类越多,造成了项目中类的数量过于庞大
    18. 2.当新增了业务,除了要添加该业务对应的方法(load),同时还要改动原有的代码
    19. 3.反射相关代码,在每一个实体类对应的servlet中都存在
    20. 4.每一个servlet中都有doget、dopost方法
    21. -->
    22. </body>
    23. </html>

    再写四个servlet在com.cdl.web包下

    AddBookServlet

    1. package com.cdl.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. /**
    9. * Servlet implementation class AddBookServlet
    10. */
    11. @WebServlet("/book/add")
    12. public class AddBookServlet extends HttpServlet {
    13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doPost(request, response);
    15. }
    16. /**
    17. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    18. */
    19. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    20. System.out.println("处理书籍的增加业务,调用BookBiz");
    21. }
    22. }

    DelBookServlet

    1. package com.cdl.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/del")
    9. public class DelBookServlet extends HttpServlet {
    10. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    11. doPost(request, response);
    12. }
    13. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. System.out.println("处理书籍的删除业务,调用BookBiz");
    15. }
    16. }

    EditBookServlet

    1. package com.cdl.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. /**
    9. * Servlet implementation class EditBookServlet
    10. */
    11. @WebServlet("/book/edit")
    12. public class EditBookServlet extends HttpServlet {
    13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doPost(request, response);
    15. }
    16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. System.out.println("处理书籍的编辑业务,调用BookBiz");
    18. }
    19. }

    ListBookServlet

    1. package com.cdl.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. /**
    9. * Servlet implementation class EditBookServlet
    10. */
    11. @WebServlet("/book/list")
    12. public class ListBookServlet extends HttpServlet {
    13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    14. doPost(request, response);
    15. }
    16. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    17. System.out.println("处理书籍的查询业务,调用BookBiz");
    18. }
    19. }

    当点击增加控制台输出

    点其他时

     

    三、类过多的优化

    建一个BookServlet

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

     Demo01.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>Insert title here</title>
    8. </head>
    9. <body>
    10. <h3>目前增删改查的方法</h3>
    11. <a href="${pageContext.request.contextPath }/book/add">增加</a>
    12. <a href="${pageContext.request.contextPath }/book/del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book/edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book/list">查询</a>
    15. <!--
    16. 上述问题:
    17. 1.关于单个实体/表操作场景越多,需要新建的类越多,造成了项目中类的数量过于庞大
    18. 2.当新增了业务,除了要添加该业务对应的方法(load),同时还要改动原有的代码
    19. 3.反射相关代码,在每一个实体类对应的servlet中都存在
    20. 4.每一个servlet中都有doget、dopost方法
    21. -->
    22. <h3>类数量过多问题的优化</h3>
    23. <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
    24. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    25. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    26. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
    27. <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
    28. </body>
    29. </html>

    结果

    点击修改和删除 控制台:

     

     四、反射优化

    改变三中的BookServlet

    1. package com.cdl.web;
    2. import java.io.IOException;
    3. import java.lang.reflect.Method;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. @WebServlet("/book.action")
    10. public class BookServlet extends HttpServlet {
    11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. doPost(request, response);
    13. }
    14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
    16. String methodName = request.getParameter("methodName");
    17. // methodName可能是add/del/edit/list/load/xxx/yyy/aaa...
    18. // 前台传递什么方法,就调用当前类的对应方法
    19. try {
    20. Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    21. m.setAccessible(true);
    22. // 调用当前类实例的methodName方法
    23. m.invoke(this, request,response);
    24. } catch (Exception e) {
    25. // TODO Auto-generated catch block
    26. e.printStackTrace();
    27. }
    28. // if("add".equals(methodName)){
    29. // 如果前台传递到后台的是一个新增的请求,那么后台就调用新增方法
    30. // add(req,resp);
    31. // }
    32. // else if("del".equals(methodName)) {
    33. // del(req,resp);
    34. // }
    35. // else if("edit".equals(methodName)) {
    36. // edit(req,resp);
    37. // }
    38. // else if("list".equals(methodName)) {
    39. // list(req,resp);
    40. // }
    41. // else if("load".equals(methodName)) {
    42. // load(req,resp);
    43. // }
    44. }
    45. private void list(HttpServletRequest req, HttpServletResponse resp) {
    46. System.out.println("在用一个servlet中调用 list 方法");
    47. }
    48. private void load(HttpServletRequest req, HttpServletResponse resp) {
    49. System.out.println("在用一个servlet中调用 list 方法");
    50. }
    51. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    52. System.out.println("在用一个servlet中调用 edit 方法");
    53. }
    54. private void del(HttpServletRequest req, HttpServletResponse resp) {
    55. System.out.println("在用一个servlet中调用 del 方法");
    56. }
    57. private void add(HttpServletRequest req, HttpServletResponse resp) {
    58. System.out.println("在用一个servlet中调用 add 方法");
    59. }
    60. }

    和三一致效果

    五、MVC工作原理以及对应打码

     

    在com.cdl.web中建一个OrderServlet

    1. package com.cdl.web;
    2. import java.io.IOException;
    3. import java.lang.reflect.Method;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.annotation.WebServlet;
    6. import javax.servlet.http.HttpServlet;
    7. import javax.servlet.http.HttpServletRequest;
    8. import javax.servlet.http.HttpServletResponse;
    9. @WebServlet("/order.action")
    10. public class OrderServlet extends HttpServlet {
    11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    12. doPost(request, response);
    13. }
    14. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    15. // 为了区分当前请求的目的,增删改查的目的,就从前台将要调用的方法名传递到后台
    16. String methodName = request.getParameter("methodName");
    17. // methodName可能是add/del/edit/list/load/xxx/yyy/aaa...
    18. // 前台传递什么方法,就调用当前类的对应方法
    19. try {
    20. Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    21. m.setAccessible(true);
    22. // 调用当前类实例的methodName方法
    23. m.invoke(this, request,response);
    24. } catch (Exception e) {
    25. // TODO Auto-generated catch block
    26. e.printStackTrace();
    27. }
    28. // if("add".equals(methodName)){
    29. // 如果前台传递到后台的是一个新增的请求,那么后台就调用新增方法
    30. // add(req,resp);
    31. // }
    32. // else if("del".equals(methodName)) {
    33. // del(req,resp);
    34. // }
    35. // else if("edit".equals(methodName)) {
    36. // edit(req,resp);
    37. // }
    38. // else if("list".equals(methodName)) {
    39. // list(req,resp);
    40. // }
    41. // else if("load".equals(methodName)) {
    42. // load(req,resp);
    43. // }
    44. }
    45. private void list(HttpServletRequest req, HttpServletResponse resp) {
    46. System.out.println("在用一个order中调用 list 方法");
    47. }
    48. private void load(HttpServletRequest req, HttpServletResponse resp) {
    49. System.out.println("在用一个order中调用 list 方法");
    50. }
    51. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    52. System.out.println("在用一个order中调用 edit 方法");
    53. }
    54. private void del(HttpServletRequest req, HttpServletResponse resp) {
    55. System.out.println("在用一个order中调用 del 方法");
    56. }
    57. private void add(HttpServletRequest req, HttpServletResponse resp) {
    58. System.out.println("在用一个order中调用 add 方法");
    59. }
    60. }

    Demo02.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>Insert title here</title>
    8. </head>
    9. <body>
    10. <h3>目前增删改查的方法</h3>
    11. <a href="${pageContext.request.contextPath }/book/add">增加</a>
    12. <a href="${pageContext.request.contextPath }/book/del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book/edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book/list">查询</a>
    15. <!--
    16. 上述问题:
    17. 1.关于单个实体/表操作场景越多,需要新建的类越多,造成了项目中类的数量过于庞大
    18. 2.当新增了业务,除了要添加该业务对应的方法(load),同时还要改动原有的代码
    19. 3.反射相关代码,在每一个实体类对应的servlet中都存在
    20. 4.每一个servlet中都有doget、dopost方法
    21. -->
    22. <h3>类数量过多问题的优化</h3>
    23. <a href="${pageContext.request.contextPath }/book.action?methodName=add">增加</a>
    24. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    25. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    26. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
    27. <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
    28. <h3>订单类CRUD</h3>
    29. <a href="${pageContext.request.contextPath }/order.action?methodName=add">增加</a>
    30. <a href="${pageContext.request.contextPath }/order.action?methodName=del">删除</a>
    31. <a href="${pageContext.request.contextPath }/order.action?methodName=edit">修改</a>
    32. <a href="${pageContext.request.contextPath }/order.action?methodName=list">查询</a>
    33. <a href="${pageContext.request.contextPath }/order.action?methodName=load">回显</a>
    34. </body>
    35. </html>


    运行代码:

     建一个com.cdl.framework的包

    建一个DispatcherServlet

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

    ActionSupport

    1. package com.cdl.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可能是add/del/edit/list/load/xxx/yyy/aaa...
    10. // 前台传递什么方法,就调用当前类的对应方法
    11. try {
    12. Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    13. //打开访问权限
    14. m.setAccessible(true);
    15. // 调用当前类实例的methodName方法
    16. m.invoke(this, req,resp);
    17. } catch (Exception e) {
    18. // TODO: handle exception
    19. e.printStackTrace();
    20. }
    21. }
    22. private void list(HttpServletRequest req, HttpServletResponse resp) {
    23. System.out.println("在用一个servlet中调用list方法");
    24. }
    25. private void load(HttpServletRequest req, HttpServletResponse resp) {
    26. System.out.println("在用一个servlet中调用list方法");
    27. }
    28. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    29. System.out.println("在用一个servlet中调用edit方法");
    30. }
    31. private void del(HttpServletRequest req, HttpServletResponse resp) {
    32. System.out.println("在用一个servlet中调用del方法");
    33. }
    34. private void add(HttpServletRequest req, HttpServletResponse resp) {
    35. System.out.println("在用一个servlet中调用add方法");
    36. }
    37. }

    Action

    1. package com.cdl.framework;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. /**
    5. * 子控制器
    6. * 对应请求的处理人
    7. * @author 陈冬丽
    8. *
    9. */
    10. public interface Action {
    11. void execute(HttpServletRequest req,HttpServletResponse resp);
    12. }

  • 相关阅读:
    RabbitMQ之消息应答和持久化
    k8s-2 集群升级
    ECharts数据可视化项目
    小程序与uniapp如何进行传参
    计算机网络第五章问答题
    B树、B+树、红黑树的定义、之间的区别、优缺点、数据结构、应用等
    软件工程-第7章 面向对象方法基础
    造一个CPU
    (C语言)背答案
    人大与加拿大女王大学金融硕士——带你了解GMAT考试为何如此重要
  • 原文地址:https://blog.csdn.net/weixin_62735525/article/details/125455529