• 自定义mvc框架实现


    文章目录

    一、中央控制器动态加载存储子控制器

    分析:

    1.通过建模我们可以知道,最终configModel对象会包含config.xml中所有子控制器的信息

    2.同时为了解决中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入congigModel对象即可

    代码展示:

    config.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <config>
    3. <action path="/book" type="com.cdl.web.BookAction">
    4. <forward name="failed" path="/reg.jsp" redirect="false" />
    5. <forward name="success" path="/login.jsp" redirect="true" />
    6. </action>
    7. </config>

    对DispatcherServlet进行改造

    1. package com.cdl.framework;
    2. import java.io.IOException;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. import javax.management.RuntimeErrorException;
    6. import javax.servlet.ServletException;
    7. import javax.servlet.annotation.WebServlet;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import com.cdl.web.BookAction;
    12. /**
    13. * 中央控制器:
    14. * 主要职能:接受浏览器请求,找到对应的处理人
    15. *
    16. *
    17. * @author 陈冬丽
    18. *
    19. */
    20. @WebServlet("*.action")
    21. public class DispatcherServlet extends HttpServlet{
    22. //private Map<String, Action> actions=new HashMap<String, Action>();
    23. // 通过建模我们可以知道,最终configModel对象会包含config.xml中所有子控制器的信息
    24. // 同时为了解决中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入congigModel对象即可
    25. private ConfigModel ConfigModel;
    26. // 程序启动时,只会加载一次
    27. @Override
    28. public void init() throws ServletException {
    29. //actions.put("/book", new BookAction());
    30. // actions.put("/order", new BooKAction());
    31. try {
    32. ConfigModel = (ConfigModel)ConfigModelFactory.bulid();
    33. } catch (Exception e) {
    34. // TODO Auto-generated catch block
    35. e.printStackTrace();
    36. }
    37. }
    38. @Override
    39. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    40. doPost(req, resp);
    41. }
    42. @Override
    43. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    44. //http://localhost:8080/mvc/book.aciton?methodName=list
    45. String uri = req.getRequestURI();
    46. // 要拿到/book,就是最后一个/到最后一个点的位置
    47. uri=uri.substring(uri.lastIndexOf("/")
    48. , uri.lastIndexOf("."));
    49. //Action action = actions.get(uri);
    50. //相比于上一种从map集合中获取子控制器,当前需要获取config.xml中的全路径名,然后反射实例化
    51. ActionModel actionModel = ConfigModel.pop(uri);
    52. if(actionModel == null) {
    53. throw new RuntimeException("action 配置 error");
    54. }
    55. String type = actionModel.getType();//配置文件中的全路径名 action子控制器的全路径名
    56. try {
    57. Action action = (Action) Class.forName(type).newInstance();//action的实例
    58. action.execute(req, resp);
    59. } catch (Exception e) {
    60. e.printStackTrace();
    61. }
    62. }
    63. }

    页面代码:Demo01

    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.action?methodName=add">增加</a>
    12. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
    15. <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
    16. </body>
    17. </html>

     运行效果:

     点击增加

    二、参数传递封装的优化

    以增加为例

    Demo01:

    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.action?methodName=add&bid=989898&bname=laoliu&price=89">增加</a>
    12. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
    15. <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
    16. </body>
    17. </html>

    建一个com.cdl.entity的包 在其内建一个Book的实体类

    1. package com.cdl.entity;
    2. /**
    3. * 书的实体类
    4. * @author 陈冬丽
    5. *
    6. */
    7. public class Book {
    8. private int bid;
    9. private String bname;
    10. private float price;
    11. public int getBid() {
    12. return bid;
    13. }
    14. public void setBid(int bid) {
    15. this.bid = bid;
    16. }
    17. public String getBname() {
    18. return bname;
    19. }
    20. public void setBname(String bname) {
    21. this.bname = bname;
    22. }
    23. public float getPrice() {
    24. return price;
    25. }
    26. public void setPrice(float price) {
    27. this.price = price;
    28. }
    29. @Override
    30. public String toString() {
    31. return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
    32. }
    33. }

    优化前的BookAction

    1. package com.cdl.web;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import com.cdl.entity.Book;
    5. import com.cdl.framework.Action;
    6. import com.cdl.framework.ActionSupport;
    7. public class BookAction extends ActionSupport {
    8. private void list(HttpServletRequest req, HttpServletResponse resp) {
    9. System.out.println("在用一个servlet中调用 list 方法");
    10. }
    11. private void load(HttpServletRequest req, HttpServletResponse resp) {
    12. System.out.println("在用一个servlet中调用 list 方法");
    13. }
    14. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    15. System.out.println("在用一个servlet中调用 edit 方法");
    16. }
    17. private void del(HttpServletRequest req, HttpServletResponse resp) {
    18. System.out.println("在用一个servlet中调用 del 方法");
    19. }
    20. private void add(HttpServletRequest req, HttpServletResponse resp) {
    21. String bid = req.getParameter("bid");
    22. String bname = req.getParameter("bname");
    23. String price = req.getParameter("price");
    24. Book book = new Book();
    25. book.setBid(Integer.valueOf(bid));
    26. book.setBname(bname);
    27. book.setPrice(Float.valueOf(price));
    28. System.out.println("在用一个servlet中调用 add 方法"+book);
    29. }
    30. }

    在界面点击增加之后:

     

     问题:若前端也就是界面联合了多张表,那么在传递参数时就不止3个属性,就会反复的写String bname = req.getParameter("bname"); 这种代码

    BookAction

    1. package com.cdl.web;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import com.cdl.entity.Book;
    5. import com.cdl.framework.Action;
    6. import com.cdl.framework.ActionSupport;
    7. import com.cdl.framework.ModelDriven;
    8. /**
    9. * 子控制器
    10. * @author 陈冬丽
    11. *
    12. *
    13. */
    14. public class BookAction extends ActionSupport implements ModelDriven<Book>{
    15. private Book book = new Book();
    16. private void list(HttpServletRequest req, HttpServletResponse resp) {
    17. System.out.println("在用一个servlet中调用 list 方法");
    18. }
    19. private void load(HttpServletRequest req, HttpServletResponse resp) {
    20. System.out.println("在用一个servlet中调用 list 方法");
    21. }
    22. private void edit(HttpServletRequest req, HttpServletResponse resp) {
    23. System.out.println("在用一个servlet中调用 edit 方法");
    24. }
    25. private void del(HttpServletRequest req, HttpServletResponse resp) {
    26. System.out.println("在用一个servlet中调用 del 方法");
    27. }
    28. private void add(HttpServletRequest req, HttpServletResponse resp) {
    29. // String bid = req.getParameter("bid");
    30. // String bname = req.getParameter("bname");
    31. // String price = req.getParameter("price");
    32. //Book book = new Book();
    33. // book.setBid(Integer.valueOf(bid));
    34. // book.setBname(bname);
    35. // book.setPrice(Float.valueOf(price));
    36. System.out.println("在用一个servlet中调用 add 方法"+book);
    37. }
    38. @Override
    39. public Book getModel() {
    40. return book;
    41. }
    42. }

    创建一个接口ModelDriven

    1. package com.cdl.framework;
    2. /**
    3. * 模型驱动接口:接收jsp传递的参数,并且封装到实体类中
    4. * @author 陈冬丽
    5. *
    6. *
    7. */
    8. public interface ModelDriven<T> {
    9. //拿到将要封装的类实例 ModelDriven.getModel -->new Book();
    10. T getModel();
    11. }

    改造 DispatcherServlet

    1. package com.cdl.framework;
    2. import java.io.IOException;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. import javax.management.RuntimeErrorException;
    6. import javax.servlet.ServletException;
    7. import javax.servlet.annotation.WebServlet;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import org.apache.commons.beanutils.BeanUtils;
    12. import org.apache.commons.beanutils.PropertyUtils;
    13. import com.cdl.web.BookAction;
    14. /**
    15. * 中央控制器:
    16. * 主要职能:接受浏览器请求,找到对应的处理人
    17. *
    18. * @author 陈冬丽
    19. *
    20. */
    21. @WebServlet("*.action")
    22. public class DispatcherServlet extends HttpServlet{
    23. //private Map<String, Action> actions=new HashMap<String, Action>();
    24. // 通过建模我们可以知道,最终configModel对象会包含config.xml中所有子控制器的信息
    25. // 同时为了解决中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入congigModel对象即可
    26. private ConfigModel ConfigModel;
    27. // 程序启动时,只会加载一次
    28. @Override
    29. public void init() throws ServletException {
    30. //actions.put("/book", new BookAction());
    31. // actions.put("/order", new BooKAction());
    32. try {
    33. ConfigModel = (ConfigModel)ConfigModelFactory.bulid();
    34. } catch (Exception e) {
    35. // TODO Auto-generated catch block
    36. e.printStackTrace();
    37. }
    38. }
    39. @Override
    40. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    41. doPost(req, resp);
    42. }
    43. @Override
    44. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    45. //http://localhost:8080/mvc/book.aciton?methodName=list
    46. String uri = req.getRequestURI();
    47. // 要拿到/book,就是最后一个/到最后一个点的位置
    48. uri=uri.substring(uri.lastIndexOf("/")
    49. , uri.lastIndexOf("."));
    50. //Action action = actions.get(uri);
    51. //相比于上一种从map集合中获取子控制器,当前需要获取config.xml中的全路径名,然后反射实例化
    52. ActionModel actionModel = ConfigModel.pop(uri);
    53. if(actionModel == null) {
    54. throw new RuntimeException("action 配置 error");
    55. }
    56. String type = actionModel.getType();//配置文件中的全路径名 action子控制器的全路径名
    57. try {
    58. Action action = (Action) Class.forName(type).newInstance();//action的实例
    59. //因为action是bookAction而bookAction实现了ModelDriven接口
    60. if(action instanceof ModelDriven) {
    61. //所以可以将其进行向下转型
    62. ModelDriven md = (ModelDriven)action;
    63. //model指的是bookAction中的book类实例
    64. Object model = md.getModel();
    65. //给model中的属性赋值,要接受前端jsp传递的参数 req.getParameterMap()
    66. //PropertyUtils.getIndexedProperty(bean, name) 从某个对象中取某个值
    67. //将前端所有参数值封装进实体类
    68. BeanUtils.populate(model, req.getParameterMap());
    69. }
    70. // 目标:正式调用此方法之前 book中的属性要被赋值
    71. action.execute(req, resp);
    72. } catch (Exception e) {
    73. e.printStackTrace();
    74. }
    75. }
    76. }

    当在页面点击增加和优化前一样的效果

    三、返回值页面跳转优化

    对子控制器进行改造

    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. String execute(HttpServletRequest req, HttpServletResponse resp);
    12. }

    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 String 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. m.setAccessible(true);
    14. // 调用当前类实例的methodName方法
    15. return (String) m.invoke(this, req,resp);
    16. } catch (Exception e) {
    17. // TODO Auto-generated catch block
    18. e.printStackTrace();
    19. }
    20. return null;
    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. }

    DispatcherServlet

    1. package com.cdl.framework;
    2. import java.io.IOException;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. import javax.management.RuntimeErrorException;
    6. import javax.servlet.ServletException;
    7. import javax.servlet.annotation.WebServlet;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import org.apache.commons.beanutils.BeanUtils;
    12. import org.apache.commons.beanutils.PropertyUtils;
    13. import com.cdl.web.BookAction;
    14. /**
    15. * 中央控制器:
    16. * 主要职能:接受浏览器请求,找到对应的处理人
    17. *
    18. * @author 陈冬丽
    19. *
    20. */
    21. @WebServlet("*.action")
    22. public class DispatcherServlet extends HttpServlet{
    23. //private Map<String, Action> actions=new HashMap<String, Action>();
    24. // 通过建模我们可以知道,最终configModel对象会包含config.xml中所有子控制器的信息
    25. // 同时为了解决中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入congigModel对象即可
    26. private ConfigModel ConfigModel;
    27. // 程序启动时,只会加载一次
    28. @Override
    29. public void init() throws ServletException {
    30. //actions.put("/book", new BookAction());
    31. // actions.put("/order", new BooKAction());
    32. try {
    33. ConfigModel = (ConfigModel)ConfigModelFactory.bulid();
    34. } catch (Exception e) {
    35. // TODO Auto-generated catch block
    36. e.printStackTrace();
    37. }
    38. }
    39. @Override
    40. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    41. doPost(req, resp);
    42. }
    43. @Override
    44. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    45. //http://localhost:8080/mvc/book.aciton?methodName=list
    46. String uri = req.getRequestURI();
    47. // 要拿到/book,就是最后一个/到最后一个点的位置
    48. uri=uri.substring(uri.lastIndexOf("/")
    49. , uri.lastIndexOf("."));
    50. //Action action = actions.get(uri);
    51. //相比于上一种从map集合中获取子控制器,当前需要获取config.xml中的全路径名,然后反射实例化
    52. ActionModel actionModel = ConfigModel.pop(uri);
    53. if(actionModel == null) {
    54. throw new RuntimeException("action 配置 error");
    55. }
    56. String type = actionModel.getType();//配置文件中的全路径名 action子控制器的全路径名
    57. try {
    58. Action action = (Action) Class.forName(type).newInstance();//action的实例
    59. //因为action是bookAction而bookAction实现了ModelDriven接口
    60. if(action instanceof ModelDriven) {
    61. //所以可以将其进行向下转型
    62. ModelDriven md = (ModelDriven)action;
    63. //model指的是bookAction中的book类实例
    64. Object model = md.getModel();
    65. //给model中的属性赋值,要接受前端jsp传递的参数 req.getParameterMap()
    66. //PropertyUtils.getIndexedProperty(bean, name) 从某个对象中取某个值
    67. //将前端所有参数值封装进实体类
    68. BeanUtils.populate(model, req.getParameterMap());
    69. }
    70. // 正式调用此方法之前 book中的属性要被赋值
    71. String result = action.execute(req,resp);
    72. ForwardModel forwardModel = actionModel.pop(result);
    73. // if(forwardModel == null)
    74. // throw new RuntimeException("forward config error");
    75. // /bookList.jsp /index.jsp
    76. String path = forwardModel.getPath();
    77. //拿到是否需要转发的配置
    78. boolean redirect = forwardModel.isRedirect();
    79. if(redirect)
    80. resp.sendRedirect(path);
    81. else
    82. req.getRequestDispatcher(path).forward(req, resp);
    83. } catch (Exception e) {
    84. e.printStackTrace();
    85. }
    86. }
    87. }

    ForwardModel

    1. package com.cdl.framework;
    2. /**
    3. * @author 陈冬丽
    4. *
    5. */
    6. public class ForwardModel {
    7. // <forward name="failed" path="/reg.jsp" redirect="false" />
    8. private String name;
    9. private String path;
    10. private Boolean redirect;
    11. public String getName() {
    12. return name;
    13. }
    14. public void setName(String name) {
    15. this.name = name;
    16. }
    17. public String getPath() {
    18. return path;
    19. }
    20. public void setPath(String path) {
    21. this.path = path;
    22. }
    23. public Boolean getRedirect() {
    24. return redirect;
    25. }
    26. public void setRedirect(Boolean redirect) {
    27. this.redirect = redirect;
    28. }
    29. public ForwardModel() {
    30. // TODO Auto-generated constructor stub
    31. }
    32. public ForwardModel(String name, String path, Boolean redirect) {
    33. this.name = name;
    34. this.path = path;
    35. this.redirect = redirect;
    36. }
    37. public boolean isRedirect() {
    38. return redirect;
    39. }
    40. }

    config.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <config>
    3. <action path="/book" type="com.cdl.web.BookAction">
    4. <forward name="success" path="/Demo02.jsp" redirect="false" />
    5. <forward name="failed" path="/Demo03.jsp" redirect="true" />
    6. </action>
    7. <action path="/order" type="com.cdl.web.OrderAction">
    8. <forward name="failed" path="/reg.jsp" redirect="false" />
    9. <forward name="success" path="/login.jsp" redirect="true" />
    10. </action>
    11. </config>

    界面Demo01

    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.action?methodName=add&bid=989898&bname=laoliu&price=89">增加</a>
    12. <a href="${pageContext.request.contextPath }/book.action?methodName=del">删除</a>
    13. <a href="${pageContext.request.contextPath }/book.action?methodName=edit">修改</a>
    14. <a href="${pageContext.request.contextPath }/book.action?methodName=list">查询</a>
    15. <a href="${pageContext.request.contextPath }/book.action?methodName=load">回显</a>
    16. </body>
    17. </html>

    Demo02

    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. 转发页面
    11. </body>
    12. </html>

    Demo03

    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. 重定向页面
    11. </body>
    12. </html>

    运行Demo01

     点击增加

     点击查询

     丢失项目名的解决办法

    代码段:

    DispatcherServlet

    1. //拿到是否需要转发的配置
    2. boolean redirect = forwardModel.isRedirect();
    3. if(redirect)
    4. resp.sendRedirect(req.getServletContext().getContextPath()+path);
    5. else
    6. req.getRequestDispatcher(path).forward(req, resp);

    再次点击增加时

     此时控制台:

     注意:即使在丢失项目名的情况下 还是会调用增加的方法

    四、框架配置文件可变

    DispatcherServlet

    1. package com.cdl.framework;
    2. import java.io.IOException;
    3. import java.util.HashMap;
    4. import java.util.Map;
    5. import javax.management.RuntimeErrorException;
    6. import javax.servlet.ServletException;
    7. import javax.servlet.annotation.WebServlet;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import org.apache.commons.beanutils.BeanUtils;
    12. import org.apache.commons.beanutils.PropertyUtils;
    13. import com.cdl.web.BookAction;
    14. /**
    15. * 中央控制器:
    16. * 主要职能:接受浏览器请求,找到对应的处理人
    17. *
    18. * @author 陈冬丽
    19. *
    20. */
    21. //@WebServlet("*.action")
    22. public class DispatcherServlet extends HttpServlet{
    23. //private Map<String, Action> actions=new HashMap<String, Action>();
    24. // 通过建模我们可以知道,最终configModel对象会包含config.xml中所有子控制器的信息
    25. // 同时为了解决中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入congigModel对象即可
    26. private ConfigModel ConfigModel;
    27. // 程序启动时,只会加载一次
    28. @Override
    29. public void init() throws ServletException {
    30. //actions.put("/book", new BookAction());
    31. // actions.put("/order", new BooKAction());
    32. try {
    33. //配置地址
    34. //getInitParameter的作用是拿到web.xml中的servlet信息配置的参数
    35. String configLocation = this.getInitParameter("configLocation");
    36. if(configLocation == null || "".equals(configLocation))
    37. ConfigModel = ConfigModelFactory.bulid();
    38. else
    39. ConfigModel = ConfigModelFactory.bulid(configLocation);
    40. } catch (Exception e) {
    41. // TODO Auto-generated catch block
    42. e.printStackTrace();
    43. }
    44. }
    45. @Override
    46. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    47. doPost(req, resp);
    48. }
    49. @Override
    50. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    51. //http://localhost:8080/mvc/book.aciton?methodName=list
    52. String uri = req.getRequestURI();
    53. // 要拿到/book,就是最后一个/到最后一个点的位置
    54. uri=uri.substring(uri.lastIndexOf("/")
    55. , uri.lastIndexOf("."));
    56. //Action action = actions.get(uri);
    57. //相比于上一种从map集合中获取子控制器,当前需要获取config.xml中的全路径名,然后反射实例化
    58. ActionModel actionModel = ConfigModel.pop(uri);
    59. if(actionModel == null) {
    60. throw new RuntimeException("action 配置 error");
    61. }
    62. String type = actionModel.getType();//配置文件中的全路径名 action子控制器的全路径名
    63. try {
    64. Action action = (Action) Class.forName(type).newInstance();//action的实例
    65. //因为action是bookAction而bookAction实现了ModelDriven接口
    66. if(action instanceof ModelDriven) {
    67. //所以可以将其进行向下转型
    68. ModelDriven md = (ModelDriven)action;
    69. //model指的是bookAction中的book类实例
    70. Object model = md.getModel();
    71. //给model中的属性赋值,要接受前端jsp传递的参数 req.getParameterMap()
    72. //PropertyUtils.getIndexedProperty(bean, name) 从某个对象中取某个值
    73. //将前端所有参数值封装进实体类
    74. BeanUtils.populate(model, req.getParameterMap());
    75. }
    76. // 正式调用此方法之前 book中的属性要被赋值
    77. String result = action.execute(req,resp);
    78. ForwardModel forwardModel = actionModel.pop(result);
    79. // if(forwardModel == null)
    80. // throw new RuntimeException("forward config error");
    81. // /bookList.jsp /index.jsp
    82. String path = forwardModel.getPath();
    83. //拿到是否需要转发的配置
    84. boolean redirect = forwardModel.isRedirect();
    85. if(redirect)
    86. resp.sendRedirect(req.getServletContext().getContextPath()+path);
    87. else
    88. req.getRequestDispatcher(path).forward(req, resp);
    89. } catch (Exception e) {
    90. e.printStackTrace();
    91. }
    92. }
    93. }

    web.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    3. <display-name>t280_mvc</display-name>
    4. <servlet>
    5. <servlet-name>mvc</servlet-name>
    6. <servlet-class>com.cdl.framework.DispatcherServlet</servlet-class>
    7. <init-param>
    8. <param-name>configLaction</param-name>
    9. <param-value>/wuyanzu</param-value>
    10. </init-param>
    11. </servlet>
    12. <servlet-mapping>
    13. <servlet-name>mvc</servlet-name>
    14. <url-pattern>*.action</url-pattern>
    15. </servlet-mapping>
    16. </web-app>

     将config.xml->wuyanzu.xml

    运行Demo01点击增加和查询和三是一样的结果


  • 相关阅读:
    AI伦理:科技发展中的人性之声
    uniapp微信小程序隐私保护引导新规
    vue中常见的3块标签的介绍
    训练神经网络解决二分类问题的原理
    定制你的【Spring Boot Starter】,加速开发效率
    攻防世界WEB练习 | easyphp
    Vue2:MVVM 设计模式、Vue指令、模板语法
    【SpringSecurity】九、Base64与JWT
    Docker Compose具体应用
    Rust和Pytho写一段采集公众号代码
  • 原文地址:https://blog.csdn.net/weixin_62735525/article/details/125488668