自定义MVC(中)

简介: 自定义MVC(中)

一.MVC设计模式

概念:

MVC(Model-View-Controller)是一种常用的软件设计模式,用于组织和管理应用程序的代码。它将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller),各司其职,相互之间有明确的分工。

解释:

模型(Model):模型是应用程序的数据和业务逻辑的核心部分。它负责处理数据的存取、操作和验证,以及执行业务规则。模型通常包括数据对象、数据库交互、文件操作等。它可以从数据库、文件或其他数据源中获取数据,并对数据进行操作和更新。模型不依赖于视图和控制器,可以在不改变其他部分的情况下进行独立的测试和修改。

视图(View):视图是应用程序的用户界面,负责展示数据给用户,并接收用户的输入。视图可以是图形界面、网页、命令行界面等,根据具体的应用场景而定。视图通常从模型中获取数据,并将其呈现给用户。它可以将用户的操作发送给控制器进行处理。

控制器(Controller):控制器是模型和视图之间的桥梁,负责接受用户的输入并做出相应的响应。它从视图接收用户的操作,然后根据具体的业务逻辑调用模型进行数据处理,最后将处理结果返回给视图进行展示。控制器还可以根据需要更新模型或视图。控制器的存在使得模型和视图可以独立于对方进行修改和测试。

好处 :

模块化:MVC将应用程序分为不同的部分,使每个部分都独立于其他部分。这样可以提高代码的可读性、可测试性和可维护性。

分工明确:不同的角色负责不同的任务,使开发人员能够更好地协作,提高开发效率。

可扩展性:由于MVC遵循松耦合的原则,因此可以更容易地添加新的模型、视图和控制器,以满足应用程序的新需求。

可重用性:模型、视图和控制器之间的分离使得它们可以在不同的应用程序中重用,提高代码的复用性。

二.利用XML和反射优化MVC架构

1.步骤

(1).编写ConfigModel模型存放子控制器

(2).利用init方法初始化configModel对象

(3).通过uri获取ConfigModel中的属性(path)

(4)通过path获取到type

(5).再利用它反射获取到forward

package com.YU.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.YU.framework.model.ActionModel;
import com.YU.framework.model.ConfigModel;
import com.YU.framework.model.ConfigModelFactory;
import com.YU.web.BookAction;
import com.YU.web.OrderAction;
/**
 * ActionServlet:中央控制器
 * 
 * @author 21879
 *
 */
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
  // 定义ConfigModel存放子控制器
  private ConfigModel configModel;
  // 初始化configModel
  @Override
  public void init() throws ServletException {
    try {
      // configModel包含了所有的子控制器
      configModel = ConfigModelFactory.build();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doPost(req, resp);
  }
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String uri = req.getRequestURI();
    uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
    // 通过uri获取到ConfigModel中的path
    ActionModel actionmodel = configModel.pop(uri);
    // 判断配置XML时是否配置了path
    if (actionmodel == null)
      throw new RuntimeException("action not config");
    String type = actionmodel.getType();
    // 获取到type后利用反射获取到它的forward
    Action action;
    try {
      action = (Action) Class.forName(type).newInstance();
      action.execute(req, resp);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

注:在获取XML配置时需要判断是否配置当前属性

三.结果集页面配置

步骤:

1.修改子控制器的方法的返回值,将结果对象返回

package com.YU.framework;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器,向浏览器发送请求
 * @author 21879
 *
 */
public class Action {
  public String execute(HttpServletRequest req,HttpServletResponse resp) {
    //获取请求参数
    String methodName = req.getParameter("methodName");
    String res = "";
    try {
      Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
      m.setAccessible(true);
      res = (String) m.invoke(this, req,resp);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return res;
    }
}

2.将继承子控制器的方法的返回值修改成和子控制器一样的类型

3.获取业务代码返回值

//具体业务代码的返回值
String res = action.execute(req, resp);

4.通过返回值判断是重定向还是转发

//通过返回值判断结果是重定向还是转发
      ForwardModel forwardModel = actionmodel.pop(res);
      if(forwardModel!=null) {
        boolean redirect = forwardModel.isRedirect();
        //获取要跳转的页面
        String path = forwardModel.getPath();
        if(redirect) {
          resp.sendRedirect(req.getContextPath()+ path);
        }else {
          req.getRequestDispatcher(path).forward(req, resp);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

注意点:

1.增删改是重定向,转发会导致表单重复提交,导致数据重复操作紊乱

查询使用转发,刷新数据快,效率高

2.在重定向跳转页面的时候会导致路径错误,项目丢失

解决措施:在要跳转的Path前面加上req.getContextPath()

完整代码

package com.YU.framework;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.YU.framework.model.ActionModel;
import com.YU.framework.model.ConfigModel;
import com.YU.framework.model.ConfigModelFactory;
import com.YU.framework.model.ForwardModel;
import com.YU.web.BookAction;
import com.YU.web.OrderAction;
/**
 * ActionServlet:中央控制器
 * 
 * @author 21879
 *
 */
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
  // 定义ConfigModel存放子控制器
  private ConfigModel configModel;
  // 初始化configModel
  @Override
  public void init() throws ServletException {
    try {
      // configModel包含了所有的子控制器
      configModel = ConfigModelFactory.build();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doPost(req, resp);
  }
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String uri = req.getRequestURI();
    uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
    // 通过uri获取到ConfigModel中的path
    ActionModel actionmodel = configModel.pop(uri);
    // 判断配置XML时是否配置了path
    if (actionmodel == null)
      throw new RuntimeException("action not config");
    String type = actionmodel.getType();
    // 获取到type后利用反射获取到它的forward
    Action action;
    try {
      action = (Action) Class.forName(type).newInstance();
      //具体业务代码的返回值
      String res = action.execute(req, resp);
      //通过返回值判断结果是重定向还是转发
      ForwardModel forwardModel = actionmodel.pop(res);
      if(forwardModel!=null) {
        boolean redirect = forwardModel.isRedirect();
        //获取要跳转的页面
        String path = forwardModel.getPath();
        if(redirect) {
          resp.sendRedirect(req.getContextPath()+ path);
        }else {
          req.getRequestDispatcher(path).forward(req, resp);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

四.优化参数封装

1.获取表中类属性对象

(1)创建模型驱动接口

package com.YU.framework;
/**
 * 模型驱动接口
 * @author 21879
 *
 * @param <T>
 */
public interface ModelDriver<T> {
  T getModel();
}

2.获取到所有参数及参数req,getParamenterMap()

action = (Action) Class.forName(type).newInstance();
      //判断bookAction有没有实现ModelDriver接口
      if(action instanceof ModelDriver) {
        ModelDriver md = (ModelDriver) action;
        Object bean = md.getModel();
      }

3.将参数值封装到表对应的对象中

//利用Spring工具类将值和键存放到map集合中
 BeanUtils.populate(bean, req.getParameterMap());

注意点:

1.利用map集合将属性和值存储到模型对象中

2.要判断模型对象是否存在

五.什么是框架

一、什么是框架?

框架(Framework)是一个框子——指其约束性,也是一个架子——指其支撑性。

 IT语境中的框架,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构。在此结构上可以根据具体问题扩展、安插更多的组成部分,从而更迅速和方便地构建完整的解决问题的方案。

1)框架本身一般不完整到可以解决特定问题,但是可以帮助您快速解决特定问题;没有框架所有的工作都从零开始做,有了框架,为我们提供了一定的功能,我们就可以在框 架的基础上开发,极大的解放了生产力。不同的框架,是为了解决不同领域的问题。一定要为了解决问题才去学习框架。

2)框架天生就是为扩展而设计的;

3)框架里面可以为后续扩展的组件提供很多辅助性、支撑性的方便易用的实用工具(utilities),也就是说框架时常配套了一些帮助解决某类问题的库(libraries)或工具(tools)。java中就是一系列的jar包,其本质就是对jdk功能的扩展。

目录
相关文章
|
4月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
9月前
|
前端开发 Java
自定义mvc的增删改查
自定义mvc的增删改查
81 0
|
9月前
|
XML 前端开发 数据格式
自定义MVC引用XML配置文件实现
自定义MVC引用XML配置文件实现
81 0
|
9月前
|
设计模式 前端开发 搜索推荐
自定义mvc框架
自定义mvc框架
87 0
|
设计模式 前端开发
自定义mvc
自定义mvc
61 0
|
XML 前端开发 数据格式
自定义MVC超详细易懂----增删改查
自定义MVC超详细易懂----增删改查
126 0
|
存储 前端开发 架构师
自定义MVC实现 很详细(下)---优化版
自定义MVC实现 很详细(下)---优化版
|
存储 设计模式 前端开发
自定义MVC实现
自定义MVC实现
|
安全 Java
自定义mvc----增删改查终极篇
自定义mvc----增删改查终极篇
57 0
|
XML 设计模式 前端开发
自定义MVC---引用XML
自定义MVC---引用XML
59 0