自定义MVC框架(框架实现)

简介: 自定义MVC框架(框架实现)

一.什么是自定义MVC框架

MVC自定义框架是指基于MVC模式而构建的自定义框架,用于开发和管理特定的Web应用程序。通过自定义框架,开发者可以按照自己的需求和约定构建自己的应用程序结构,并实现对模型、视图和控制器的定制和扩展。


自定义框架通常提供了一系列工具和库,用于简化开发过程、处理路由和请求、管理数据和视图的输出等。开发者可以根据自己的项目需求,选择或编写适合的模块和扩展来拓展框架的功能。这样,开发者可以更加高效和灵活地构建符合自己需求的应用程序。


二.搭建自定义MVC框架

要自定义搭建一个基于MVC模式的框架,可以按照以下步骤进行:

1.定义目录结构:创建一个合适的目录结构,用于组织框架的各个组件和功能模块。通常包括模型、视图、控制器、配置文件、路由器等。


2.设计模型(Model):根据应用程序的需求,设计和实现模型层的代码。模型负责处理数据的获取、存储和操作。可以根据框架需求,选择相应的数据库连接方式、ORM(对象关系映射)工具等。

3.设计视图(View):设计和实现视图层的代码,用于呈现数据给用户并处理用户界面的逻辑。视图通常由HTML、CSS和客户端脚本组成。

4.设计控制器(Controller):设计和实现控制器层的代码,处理用户的请求并协调模型和视图之间的交互。控制器负责接收和解析用户的请求,调用相应的模型进行数据处理,并将最终结果传递给视图进行展示。

5.设计路由器(Router):设计和实现路由器的代码,用于将用户的请求映射到相应的控制器和动作。路由器根据不同的URL和请求方法,将请求分发给对应的控制器。

6.设计配置文件:创建一个配置文件,用于存储框架的各种配置参数,例如数据库连接信息、路由规则、密钥等。这样可以使框架更灵活和可配置。

7.编写框架核心代码:实现框架的核心代码,包括加载配置、解析路由、初始化控制器等。确保框架的基本功能和运行机制正常。

8.提供扩展机制:考虑到不同项目的需求差异,提供一些扩展机制,允许开发者根据需要添加自定义的模块和功能。

9.编写示例应用:编写一个简单的示例应用程序,演示如何使用框架进行开发。这可以作为其他开发者上手和理解框架的参考。

10.测试和优化:进行测试和调试,确保框架的稳定性和性能。根据反馈和需求进行优化和改进。

最后,你需要考虑到每个组件的互相沟通和协作,并根据实际应用需求进行完善和迭代。搭建一个自定义的MVC框架需要一定的知识和经验,同时也要对底层的技术原理有一定的了解。如果你是初学者或时间有限,也可以考虑使用已有的成熟框架,以节省开发时间和精力。


三.自定义MVC框架优化实现

3.1利用xml建模反射优化

创建配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <action path="/order" type="com.junlinyi.servlet.OrderAction">
    <!-- forward标签:没有子标签; name:字符串,同一action标签下的forward标签name值不能相同 ; path:以/开头的字符串 
      redirect:只能是false|true,允许空,默认值为false -->
    <forward name="failed" path="/reg.jsp" redirect="false" />
    <forward name="success" path="/login.jsp" redirect="true" />
  </action>
  <action path="/book" type="com.junlinyi.servlet.BookAction">
    <forward name="failed" path="/login.jsp" redirect="false" />
    <forward name="success" path="/main.jsp" redirect="true" />
  </action>
</config>

分析:action path: (/)加上你的写的项目类名    forward path:要跳转的页面   redirect:重定向判断    type:项目的路径


注意: 如果你没有配置文件就会报错,下列是展示图:报action not config 就是没有配置文件

Action :

package com.junlinyi.framework;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器
 * 真正做事,处理浏览器发送请求的类
 * @author: 君临沂
 *
 */
public class Action {
  protected String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    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;
  }
}

DispathServlet:

package com.junlinyi.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 org.apache.commons.beanutils.BeanUtils;
import com.junlinyi.model.ActionModel;
import com.junlinyi.model.ConfigModel;
import com.junlinyi.model.ConfigModelFactory;
import com.junlinyi.model.ForwardModel;
import com.junlinyi.servlet.BookAction;
import com.junlinyi.servlet.OrderAction;
/**
 * 中央控制器
 * @author: 君临沂
 *
 */
@WebServlet("*.action")
public class DispathServlet extends HttpServlet{
//    public Map<String,Action> actionMap=new HashMap<String, Action>();
//    原来所有的子控器是放到map集合中,
//  现在所有的子控制器在mvc.xml中,
//  其实就是放到configModel
  private ConfigModel configModel;
    @Override
    public void init() throws ServletException {
//      actionMap.put("/book",new BookAction());
//      actionMap.put("/order",new OrderAction());
//      初始化
      try {
//        configModel包含所有的子控制器
        configModel =ConfigModelFactory.build();
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      this.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("."));
//      Action action = actionMap.get(uri);
//      通过uri=/book,在configModel对象中找
      ActionModel actionModel = configModel.pop(uri);
//      判断
      if(actionModel == null)
        throw new RuntimeException("action not config");//你没有配置
//      拿type值 com.junlinyi.servlet.BookAction 
      String type = actionModel.getType();
//      反射实例化 BookAction
      Action action;
      try {
        action = (Action) Class.forName(type).newInstance();
//        BookAction有没有实现ModelDriver接口
        if(action instanceof ModelDriver) {
          ModelDriver md=(ModelDriver) action;
          Object bean = md.getModel();
          Map<String, String[]> map = req.getParameterMap();
          BeanUtils.populate(bean, map);
        }
//        具体业务代码执行后的返回值 add/del/upd/list的返回值===》list /tolist
        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();
      }
    }
}

ConfigModelFactory:

package com.junlinyi.model;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
 * 23种设计模式--工厂模式--创建型模式
 * @author: 君临沂
 *
 */
public class ConfigModelFactory {
    public static ConfigModel build() throws Exception {
      ConfigModel configModel=new ConfigModel();
      InputStream is = ConfigModelFactory.class.getResourceAsStream("/mvc.xml");
      SAXReader sa=new SAXReader();
      Document doc = sa.read(is);
//      System.out.println(doc.asXML());
      List<Element> actionEls = doc.selectNodes("/config/action");
      for (Element actionEl  : actionEls) {
//        System.out.println(actionEl.asXML()); 
      ActionModel actionModel=new ActionModel();
      actionModel.setPath(actionEl.attributeValue("path"));
      actionModel.setType(actionEl.attributeValue("type"));
      List<Element> forwardEls = doc.selectNodes("/config/action/forward");
      for (Element forwardEl  : forwardEls) {
        System.out.println(forwardEl.asXML()); 
        ForwardModel forwardModel=new ForwardModel();
        forwardModel.setName(forwardEl.attributeValue("name"));
        forwardModel.setPath(forwardEl.attributeValue("path"));
//        只有填false才能转发,其它都是重定向
        forwardModel.setRedirect(!"false".equals(forwardEl.attributeValue("redirect")));
        actionModel.push(forwardModel);
      }
      configModel.push(actionModel);      
      }
      return configModel;
    }
    public static void main(String[] args) throws Exception {
      ConfigModelFactory.build();
    }
}

ForwardModel:

package com.junlinyi.model;
/**
 * 
 * @author: 君临沂
 *
 */
public class ForwardModel {
  private String name;
  private String path;
  private boolean redirect;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getPath() {
    return path;
  }
  public void setPath(String path) {
    this.path = path;
  }
  public boolean isRedirect() {
    return redirect;
  }
  public void setRedirect(boolean redirect) {
    this.redirect = redirect;
  }
}

BookAction:

package com.junlinyi.servlet;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.junlinyi.entity.Book;
import com.junlinyi.framework.Action;
import com.junlinyi.framework.ModelDriver;
/**
 * BookAction类
 * @author: 君临沂
 *要有表对应的类属性对象  Book book
 *获取所有的参数值  req.getParameterMap();
 *将参数值封装到表对应的对象中
 *要做到所有的子控制器通用
 */
public  class BookAction extends Action implements ModelDriver<Book>{
  private Book book=new Book();
  public  String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Map<String, String[]> map = req.getParameterMap();
    System.out.println("恭喜你进入add....");
    req.setAttribute("hjh","小黑包来了哦");
//    resp.sendRedirect("res.jsp");
    return "tolist";
  }
  public  String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("恭喜你进入del....");
    req.setAttribute("hjh","小黑包来了哦");
//    resp.sendRedirect("res.jsp");
    return "tolist";
  }
  public  String upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("恭喜你进入upd....");
    req.setAttribute("hjh","小黑包来了哦");
//    resp.sendRedirect("res.jsp");
    return "tolist";
  }
  public  String list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("恭喜你进入list....");
    req.setAttribute("hjh","小黑包来了哦");
//    req.getRequestDispatcher("res.jsp").forward(req, resp);
    return "list";
  }
  @Override
  public Book getModel() {
    return book;
  }
}

index.jsp :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
常识:查询必然转发,增删改使用重定向
弊端:中央控制器的action容器加载不可以灵活配置<hr>
<a href="book.action?methodName=add">增加</a>
<a href="book.action?methodName=del">删除</a>
<a href="book.action?methodName=upd">修改</a>
<a href="book.action?methodName=list">查询</a>
</body>
</html>

res.jsp: ${hjh }再加点内容(方便自己测试)

结果图展示:

 

正好对应这个常识:查询必然转发,增删改使用重定向

这篇 自定义MVC框架(框架实现)就介绍到这里了,欢迎大佬来提建议哦!!!!

目录
相关文章
|
1月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
1月前
|
前端开发 Java
【案例+源码】详解MVC框架模式及其应用
【案例+源码】详解MVC框架模式及其应用
49 0
|
3月前
|
设计模式 存储 前端开发
MVC 框架的主要问题是什么?
【8月更文挑战第30天】
66 0
|
5月前
|
安全 前端开发 测试技术
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
|
6月前
|
前端开发 Java Spring
Java Web ——MVC基础框架讲解及代码演示(下)
Java Web ——MVC基础框架讲解及代码演示
62 1
|
6月前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
82 1
|
6月前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
343 1
使用Java Web框架:Spring MVC的全面指南
|
6月前
|
设计模式 前端开发 网络协议
Java Web ——MVC基础框架讲解及代码演示(上)
Java Web ——MVC基础框架讲解及代码演示
50 0
|
6月前
|
前端开发 JavaScript Java
MVC框架:SpringMVC(三)
MVC框架:SpringMVC
60 0
|
6月前
|
JSON 前端开发 JavaScript
MVC框架:SpringMVC(二)
MVC框架:SpringMVC
65 0