• 自定义mvc02


    在上次的基础上优化功能:

    目录

            1.让中央控制器动态加载存储子控制器

            2.参数传递封装优化

            3.对于方法的可执行结果转发,重定向优化

            4.框架配置文件可变


            1.让中央控制器动态加载存储子控制器

    1. package com.ruojuan.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 org.apache.commons.beanutils.BeanUtils;
    11. import org.apache.commons.beanutils.PropertyUtils;
    12. import com.ruojuan.web.BookAction;
    13. /**
    14. * 中央控制器动态加载子控制器
    15. *
    16. * 中央控制器
    17. * 主要职能:接受浏览器请求,找到对应的处理人
    18. * @author liuruojuan
    19. *
    20. * 时间:2022年6月24日下午6:21:20
    21. */
    22. //@WebServlet("*.action")
    23. public class DispatcherServlet extends HttpServlet{
    24. // private Map<String, Action> actions = new HashMap<String, Action>();
    25. /*
    26. * 通过建模可以知道configModel对象包含config.xml所有子控制器信息
    27. * 同时为了解中央控制器能够动态加载保存子控制器的信息,那么我们只需要引入configModel对象即可
    28. */
    29. private ConfigModel configModel;
    30. //程序启动时,只会加载一次
    31. @Override
    32. public void init() throws ServletException {
    33. // actions.put("/book", new BookAction());
    34. // actions.put("/book", new BookAction());
    35. try {
    36. //配置地址
    37. //getInitParameter的作用是拿到web.xml中的servlet信息配置参数
    38. String configLocation = this.getInitParameter("configLocation");
    39. if(configLocation==null||"".equals(configLocation)) {
    40. configModel = ConfigModelFactory.bulid();
    41. }
    42. else {
    43. configModel = ConfigModelFactory.bulid(configLocation);
    44. }
    45. } catch (Exception e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. @Override
    50. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    51. doPost(request, response);
    52. }
    53. @Override
    54. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    55. // TODO Auto-generated method stub
    56. String uri = request.getRequestURI();
    57. //要拿到/book,就是最后一个/到最后一个,的位子
    58. uri = uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf("."));
    59. // Action action = actions.get(uri);
    60. // 相比于上一种从map集合获取子控制器,当前需要获取config.xml中的全路径名,然后反射实例化
    61. ActionModel actionModel = configModel.pop(uri);
    62. if(actionModel == null) {
    63. throw new RuntimeException("action 配置错误");
    64. }
    65. String type = actionModel.getType();
    66. try {
    67. //type是action子控制器全路径名
    68. Action action = (Action)Class.forName(type).newInstance();
    69. //action是bookAction
    70. if(action instanceof ModelDriven) {
    71. ModelDriven md = (ModelDriven) action;
    72. //model指的是bookAction中的book实例
    73. Object model = md.getModel();
    74. //要给model中的属性赋值,要接受前端jsp参数 req.getParameterMap()
    75. //PropertyUtils.getProperty(bean, name);
    76. //将前端所有参数值封装进实体类
    77. BeanUtils.populate(model, request.getParameterMap());
    78. System.out.println(model);
    79. }
    80. //正式调用方法前,book中的属性要被赋值
    81. //action.execute(request, response);
    82. String result = action.execute(request, response);
    83. ForwardModel forwardModel = actionModel.pop(result);
    84. // if(forwardModel == null) {
    85. // throw new RuntimeException("froward config error");
    86. // }
    87. //bookList.jsp /index.jsp
    88. String path = forwardModel.getPath();
    89. //拿到是否需要转发配置
    90. boolean redirect = forwardModel.isRedirect();
    91. if(redirect) {
    92. //${pageContext.request.contextPath}
    93. response.sendRedirect(request.getServletContext().getContextPath()+path);
    94. }
    95. else {
    96. request.getRequestDispatcher(path).forward(request, response);
    97. }
    98. } catch (Exception e) {
    99. e.printStackTrace();
    100. }
    101. }
    102. }

      2.参数传递封装优化

    假设有很多的属性,这样的方式不可取

            String bid = request.getParameter("bid");
            String bname = request.getParameter("bname");
            String price = request.getParameter("price");
            Book book = new Book();
            book.setBid(Integer.valueOf(bid));
            book.setBname(bname);
            book.setPrice(Float.valueOf(price));
            //bookDao.add(book);
     

     jsp界面传值:

    <h3>参数的传递封装优化</h3>
    <a href="${pageContext.request.contextPath }/order.action?methodName=add&bid=12&bname=liaoliu&price=88">增加</a>
    <a href="${pageContext.request.contextPath }/order.action?methodName=del">删除</a>
    <a href="${pageContext.request.contextPath }/order.action?methodName=edit">修改</a>
    <a href="${pageContext.request.contextPath }/order.action?methodName=list">查看</a>
    <a href="${pageContext.request.contextPath }/order.action?methodName=load">加载</a>
     

    book实体类:

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

     BookAction

    1. package com.ruojuan.web;
    2. import java.io.IOException;
    3. import javax.servlet.ServletException;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import com.ruojuan.entity.Book;
    7. import com.ruojuan.framework.Action;
    8. import com.ruojuan.framework.ActionSupport;
    9. import com.ruojuan.framework.ModelDriven;
    10. public class BookAction extends ActionSupport implements ModelDriven<Book>{
    11. private Book book = new Book();
    12. private String list(HttpServletRequest request, HttpServletResponse response) {
    13. System.out.println("在同一个servlet中调用list方法");
    14. return "success";
    15. }
    16. private void load(HttpServletRequest request, HttpServletResponse response) {
    17. System.out.println("在同一个servlet中调用load方法");
    18. }
    19. private void edit(HttpServletRequest request, HttpServletResponse response) {
    20. System.out.println("在同一个servlet中调用edit方法");
    21. }
    22. private void del(HttpServletRequest request, HttpServletResponse response) {
    23. System.out.println("在同一个servlet中调用del方法");
    24. }
    25. private String add(HttpServletRequest request, HttpServletResponse response) {
    26. Book book = new Book();
    27. //bookDao.add(book);
    28. System.out.println("在同一个servlet中调用add方法");
    29. return "failed";
    30. }
    31. @Override
    32. public Book getModel() {
    33. return book;
    34. }
    35. }

    ActionSupport

    1. package com.ruojuan.framework;
    2. import java.io.IOException;
    3. import java.lang.reflect.Method;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. public class ActionSupport implements Action {
    8. @Override
    9. public String execute(HttpServletRequest request, HttpServletResponse response) {
    10. //未来区分当前请求的目的,增删改查的目的,就从前台讲要调用的方法名传递到后台
    11. String methodName = request.getParameter("methodName");
    12. //methodName可能是add/del/edit/list/load/xxx/...
    13. //前台传递什么方法,就调用当前类的方法
    14. try {
    15. Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
    16. m.setAccessible(true);
    17. return (String) m.invoke(this, request,response);
    18. } catch (Exception e) {
    19. e.printStackTrace();
    20. }
    21. return null;
    22. }
    23. }

    Action

    1. package com.ruojuan.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 liuruojuan
    10. *
    11. * 时间:2022年6月24日下午6:22:51
    12. */
    13. public interface Action {
    14. String execute(HttpServletRequest request, HttpServletResponse response) ;
    15. }

      3.对于方法的可执行结果转发,重定向优化

    1. //bookList.jsp /index.jsp
    2. String path = forwardModel.getPath();
    3. //拿到是否需要转发配置
    4. boolean redirect = forwardModel.isRedirect();
    5. if(redirect) {
    6. //${pageContext.request.contextPath}
    7. response.sendRedirect(request.getServletContext().getContextPath()+path);
    8. }
    9. else {
    10. request.getRequestDispatcher(path).forward(request, response);
    11. }

        4.框架配置文件可变

    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>mvc</display-name>
    4. <servlet>
    5. <servlet-name>mvc</servlet-name>
    6. <servlet-class>com.ruojuan.framework.DispatcherServlet</servlet-class>
    7. <init-param>
    8. <param-name>configLocation</param-name>
    9. <param-value>/luoluo</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>
    1. package com.ruojuan.framework;
    2. import java.io.InputStream;
    3. import java.util.List;
    4. import org.dom4j.Document;
    5. import org.dom4j.DocumentException;
    6. import org.dom4j.Element;
    7. import org.dom4j.io.SAXReader;
    8. /**
    9. * 23种设计模式之工厂模式
    10. * sessionfactory
    11. * ConfigModelFactory就是用来生产configmodel对象
    12. * 生产出来的ConfigModel对象就包含config.xml中的配置内容
    13. *
    14. * 此地生产configmodel有配置信息?
    15. * 1.解析config.xml中的配置信息
    16. * 2.将对应的配置信息分别加载进行不同的模型对象中
    17. *
    18. * @author liuruojuan
    19. *
    20. * 时间:2022年6月14日下午5:54:09
    21. */
    22. public class ConfigModelFactory {
    23. public static ConfigModel bulid(String path) throws Exception {
    24. InputStream in = ConfigModelFactory.class.getResourceAsStream(path);
    25. SAXReader sr = new SAXReader();
    26. Document read = sr.read(in);
    27. List<Element> actionEles = read.selectNodes("/config/action");
    28. ConfigModel configModel = new ConfigModel();
    29. for (Element actionEle : actionEles) {
    30. ActionModel actionModel = new ActionModel();
    31. actionModel.setPath(actionEle.attributeValue("path"));
    32. actionModel.setType(actionEle.attributeValue("type"));
    33. //将forwardmodel赋值并且添加actionmodel中
    34. List<Element> forwardEles = actionEle.selectNodes("forward");
    35. for (Element element : forwardEles) {
    36. ForwardModel forwardModel = new ForwardModel();
    37. forwardModel.setName(element.attributeValue("name"));
    38. forwardModel.setPath(element.attributeValue("path"));
    39. //redirect:只能是false|true,允许空,默认值为false
    40. forwardModel.setRedirect("true".equals(element.attributeValue("redirect")));
    41. actionModel.push(forwardModel);
    42. }
    43. configModel.push(actionModel);
    44. }
    45. return configModel;
    46. }
    47. public static ConfigModel bulid() throws Exception {
    48. String defaultPath = "/config.xml";
    49. return bulid(defaultPath);
    50. }
    51. }

  • 相关阅读:
    Bash脚本基础
    SpringCloud CircuitBreak, 熔断限流
    互联网Java工程师面试题·Java 总结篇·第六弹
    计算机毕业设计 基于SpringBoot的企业内部网络管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    redis学习四redis消息订阅、pipeline、事务、modules、布隆过滤器、缓存LRU
    代理IP与Socks5代理在跨界电商、爬虫、游戏和网络安全中的应用
    SpringFramework:Spring IOC
    pgsql/mysql/clickhouse性能对比
    基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(一)案例需求
    【DouZero】 强化学习+self play达到人类玩家斗地主水平。
  • 原文地址:https://blog.csdn.net/weixin_67338832/article/details/125495266