自定义MVC框架【中篇】

简介: 自定义MVC框架【中篇】

1.自定义MVC

自定义MVC就是去了解每个标签后的底层原理逻辑,也可以根据自己的开发需求去开发一架包来使用,这个对于架构师来说是需要掌握的

-------它的好处和用途:

  • 分离关注点:MVC架构将应用程序的不同方面(数据、展示、控制逻辑)分离开来,使得代码更易于理解和维护。开发人员可以专注于特定领域的开发,提高开发效率。
  • 可扩展性和可重用性通过将应用程序分为模型、视图和控制器,可以更容易地添加新功能或修改现有功能,而不会影响其他部分的代码。这种模块化的结构使得代码更易于重用,可以更高效地开发和维护应用程序。
  • 并行开发:MVC架构允许开发人员在不同的模块上并行工作,提高开发效率和团队协作能力。例如,模型开发人员可以同时开发数据存储和处理逻辑,视图开发人员可以同时进行用户界面设计,控制器开发人员可以编写业务逻辑。
  • 测试和调试:MVC架构使得单元测试和调试更加容易。由于模型、视图和控制器是相互独立的,可以更容易地对每个部分进行测试和调试,确保代码的质量和
  • 代码复用:MVC架构中的组件可以根据需要进行重用,提高开发效率。例如,可以使用相同的模型和控制器来支持不同的视图,或者可以使用相同的视图来展示不同的模型数据

2.优化版

注意:查询必然转发,增删改必然重定向

下面这个是优化版需要用到的配置文件,要添加什么页面,就只需要改这个配置文件就可以了

DispatherAction

--------因为要将这个做成架包,所以里面的东西不能是死的,不然就会有新的就会改变,

    所以我们就用到了建模,将它变成活,到时候只要在配置文件里面添加即可

    以前都是将子控制器放在Map集合中,现在要将其放在MVC.XML文件中

package com.sy.framwork;
import java.io.IOException;
import javax.servlet.ServletConfig;
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.sy.framwork.model.ActionModel;
import com.sy.framwork.model.ConfigModel;
import com.sy.framwork.model.ConfigModelFactory;
import com.sy.framwork.model.ForwardModel;
/**
 * 中央控制器
 * 
 * @author W
 *
 */
@WebServlet("*.action")
public class DispatherAction extends HttpServlet {
  private ConfigModel configmodel;//配置文件中最大的模型
  @Override
  public void init(ServletConfig config) throws ServletException {
    try {
      configmodel = ConfigModelFactory.build();//调用获取配置文件数据的方法
      System.out.println(configmodel);
    } 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 url = req.getRequestURI();
    url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
    ActionModel actionModel = configmodel.pop(url);//通过请求路径拿到action标签
    if(actionModel==null) {//如果配置出现错误,那么就抛出一个异常
      new RuntimeException("not config error");
    }
    String type = actionModel.getType();//全路径
    try {
      Action  action = (Action) Class.forName(type).newInstance();//动态实例化处理操作的类
      if(action instanceof ModelDriver) {//如果这个类实现了ModelDriver接口
        ModelDriver md = (ModelDriver)action;//那么就将它转型成ModelDriver
        Object model = md.getModel();//调用方法(返回需要封装的实体)
        BeanUtils.populate(model, req.getParameterMap());//利用工具类将获取到的参数封装到实体中
      }
      String execute = action.execute(req, resp);//调用操作的方法
      ForwardModel forwardModel = actionModel.pop(execute);//通过name值拿到action中的forward
      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();
    }
  }
}

这个类主要是获取路径,从配置文件中获取,通过截取的获取路径进行执行浏览器传来的请求。这里面因为有些要带参数,所以要进行判断,是否为重定向,否则为转发

Action类

这个里面就是改变了方法的返回参数

package com.sy.framwork;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Action {
  public String execute(HttpServletRequest request, HttpServletResponse response) {
    //反射的代码
    String methodname = request.getParameter("methodname");
    String result="";
    try {
      Method m=this.getClass().getDeclaredMethod(methodname, HttpServletRequest.class,HttpServletResponse.class);
    m.setAccessible(true);
    result=(String) m.invoke(this, request,response);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
}

Servlet方法类(演示一遍)

package com.sy.servlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sy.entity.Book;
import com.sy.framwork.Action;
import com.sy.framwork.ModelDriver;
/**
 * book类需要进行的业务操作
 * @author W
 *
 */
public class BookAction extends Action implements ModelDriver<Book>{
private Book book=new Book();
  public String List(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("BookAction..查询.");
    return "redirect";
  }
  public String upd(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("BookAction..修改.");  
    return "forward";
  }
  public String del(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("BookAction..删除.");
    return "forward";
  }
  public String add(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("BookAction..增加.");
    return "forward";
  }
  @Override
  public Book getModel() {
    return book;
  }
}

3.Model

接下来是一些之前也发布过的建模,一些逻辑代码

3.1ConfigModel类

package com.sy.framwork.model;
import java.util.HashMap;
import java.util.Map;
public class ConfigModel {
  // config
  // actionModel在configModel中是唯一的,那么就会有一个容器(也就是属性),能够一对一的去存储actionModel
  private Map<String, ActionModel> actionMap=new HashMap<String, ActionModel>();
//  在configModel中能够添加actionModel
  public void push(ActionModel actionModel) {
    actionMap.put(actionModel.getPath(), actionModel);
  }
  //通过path在config里面拿到action
  public  ActionModel pop(String path) {
    return actionMap.get(path);
  }
  public static void main(String[] args) throws Exception {
    //获取第二个action中第二个forward的path
//    ConfigModel configModel = new ConfigModel();
//    ActionModel actionModel = configModel.pop("/loginAction");
//    ForwardModel forwardModel = actionModel.pop("success");
//    System.out.println(forwardModel.getPath());
    //在这里,我们需要用到设计模式中的工厂模式去获取xml中的内容
    ConfigModel build = ConfigModelFactory.build();//实例ConfigModelFactory,调用build方法
    ActionModel pop = build.pop("/loginAction");//第二个action的path属性值
    String path1 = pop.getPath();
    System.out.println(path1);
    ForwardModel pop2 = pop.pop("success");//第二个forward的name属性值
    String path2 = pop2.getPath();
    System.out.println(path2);
  }
}

3.2ConfigFactoryModel (工厂模型)

这里面的逻辑是比较强的,需要好好去理解,我们看到那个配置文件,有三个标签config,action,forword,这三者是层层包裹的,所以当config里面需要东西时,需要保证action里面有东西,那么就需要保证forword里面有东西。获取里面的属性

 

package com.sy.framwork.model;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class ConfigModelFactory {
public static ConfigModel build() throws Exception {
  ConfigModel configModel = new ConfigModel();//示例ConfigModel
  InputStream in = ConfigModelFactory.class.getResourceAsStream("/mvc.xml");//获取流
  SAXReader sr = new SAXReader();
  Document read = sr.read(in);//读流
  List<Element> actionEles = read.selectNodes("/config/action");//获取节点
  //填充内容到ActionModel
  for (Element actionEle : actionEles) {
    ActionModel actionModel = new ActionModel();//实例
    actionModel.setPath(actionEle.attributeValue("path"));//path
    actionModel.setType(actionEle.attributeValue("type"));//type
    //填充内容到ForwardModel
    List<Element> forwardEles = actionEle.selectNodes("forward");
    for (Element forwardEle : forwardEles) {
      ForwardModel forwardModel = new ForwardModel();//实例
      forwardModel.setName(forwardEle.attributeValue("name"));//name
      forwardModel.setPath(forwardEle.attributeValue("path"));//path
      //因为redirect是Boolean类型,所以与上述操作有些许不一样
      forwardModel.setRedirect(!"false".equals(forwardEle.attribute("redirect")));
      actionModel.push(forwardModel);//把forwardModel的内容加到actionModel中
    }
    configModel.push(actionModel);//把actionModel的内容加到configModel中
  }
  return configModel; 
}
public static void main(String[] args) throws Exception {
  ConfigModel build = ConfigModelFactory.build();
  System.out.println(build);
//  ActionModel actionModel = configModel.pop("/loginAction");
//  ForwardModel forwardModel = actionModel.pop("success");
//  System.out.println(forwardModel.getPath());
  ActionModel pop = build.pop("/loginAction");
  System.out.println(pop.getType());
}
}

3.3ActionModel

package com.sy.framwork.model;
import java.util.HashMap;
import java.util.Map;
public class ActionModel {
  // action
  // forwardModel在actionModel中是唯一的,那么在actionModel中会有一个容器(属性),可以一对一存储forwardModel
  // actionModel中还有两个属性:path和type
  private String path;
  private String type;
  private Map<String, ForwardModel> forwardMap = new HashMap<>();
  public ActionModel() {
    // TODO Auto-generated constructor stub
  }
  public String getPath() {
    return path;
  }
  public void setPath(String path) {
    this.path = path;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  // 在actionModel中能够添加forwardModel
  public void push(ForwardModel forwardModel) {
    forwardMap.put(forwardModel.getName(), forwardModel);
  }
  // 通过name值在action中拿到forward
  public ForwardModel pop(String name) {
    return forwardMap.get(name);
  }
}

3.4ForwordModel

package com.sy.framwork.model;
public class ForwardModel {
  // forwardModel中有属性:name,path,redirect
  private  String name;
  private String path;
  private boolean redirect;
  public ForwardModel() {
    // TODO Auto-generated constructor stub
  }
  public ForwardModel(String name, String path, boolean redirect) {
    super();
    this.name = name;
    this.path = path;
    this.redirect = 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;
  }
  @Override
  public String toString() {
    return "ForwardModel [name=" + name + ", path=" + path + ", redirect=" + redirect + "]";
  }
}

以上就是配置文件需要的Model

4.输出结果:

 

 

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