如何实现自定义MVC框架(进阶版本)

简介: 如何实现自定义MVC框架(进阶版本)

一.优化MVC框架

1.1优化的思路:

相比我们上篇所讲的MVC框架,我们今天所要优化的代码是要更加的方便,我们只要在一个配置文件中改变我们要传递的对象和对象的路径就能够实现一个增删改查的操作。

1.2优化的代码区域

1.中央控制器的action容器变成一个配置文件(将集合➡配置文件,作用:配置文件的内容是可以随时修改的)

2.我们反射代码调用具体的业务逻辑代码。(能够减少转发,重定向的代码)

3.从jsp页面传递参数到servlet的代码优化。

注意:查看使用转发,增删改使用重定向(只会提交一次)。

1.3怎么使用代码实现优化MVC框架?

1.优化中央控制器的action容器

 

创建一个conf文件进行保存请求对象(所以我们用一个公共的用来存前台发送的地址请求。)

注意:只能创建Foload文件夹,在里面配置xml文件,用来存放将来要实例化的对象

 

 

创建模型对象作用:用于连接xml与中央控制器。将页面传递的内容放到configmodel中去,关于如何创建模型对象我在如何创建模型对象中已经详细说明了

注意:这里记得要导包;

更改的地方:

(1) 改变用configmodel保存

(2)通过工厂获取内容

(3) 改变用模型的方式获取url

(4)根据反射获取到实例的对象(根据URL)

 

但我们运行有path的,path值是对的,我们就能够成功!!!

 

具体实现代码:

DispatherServlet(中央控制器)类

package com.lya.farmework;
import java.io.IOException;
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.lya.model.ActionModel;
import com.lya.model.ConfigModel;
import com.lya.model.ConfigModelFactory;
import com.lya.model.ForwardModel;
/**
 * 李永安
 */
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  // 定以Map接收请求
  // public Map<String, Action> actionMap = new HashMap<String, Action>();
  // (1) 改变用configmodel保存
  private ConfigModel configmodel;
  @Override
  public void init() throws ServletException {// 根据book找到BookAction
    // actionMap.put("/book", new BookAction());
    // (2)通过工厂获取内容
    try {
      configmodel = ConfigModelFactory.build();
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    this.doPost(request, response);
  }
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // 1.首先获取请求路径名.
    String url = request.getRequestURI();
    // 2.根据路径名截取到对应的请求.
    url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
    // 3.根据请求获取到对应的子控制器Action.
    // Action action = actionMap.get(url);
    // (3) 改变用模型的方式获取url
    // 通过/book找对应类的路径
    ActionModel actionModel = configmodel.pop(url);
    // 这里要判空,防止我们大意没有改或写
    if (actionModel == null) {
      throw new RuntimeException("action not config !!!!");
    } else {
      String type = actionModel.getType();// 是通过/book获取到xml配置的路径
      // (3)这里给据反射获取到实例的对象(根据URL)
      try {
        Action action = (Action) Class.forName(type).newInstance();
        if(action instanceof ModelDriver) {
          ModelDriver md = (ModelDriver) action;
          Object bean = md.getModel();
          Map<String, String[]> parameterMap = request.getParameterMap();
//          BeanUtils---------设值到action中
          BeanUtils.populate(bean, parameterMap);
        }
        //execute------list/tolist 
        String execute = action.execute(request, response);
        ForwardModel ForwardModel = actionModel.pop(execute);
        if(ForwardModel!=null) {
          boolean redirect = ForwardModel.isRedirect();
          String path = ForwardModel.getPath();
          if(redirect) {//是重定向(丢失路径 + request.getContextPath()+ "/")
            response.sendRedirect(request.getContextPath()+ "/"+ path);
          }else {
            request.getRequestDispatcher(path).forward(request, response);
          }
        }
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
}

Action(子控制器类)

package com.lya.farmework;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器
 * 
 * @author :JAVA-李永安
 * @date :2023年6月29日 下午7:38:35
 */
@WebServlet("/Action")
public class Action extends HttpServlet {
  protected String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String methodName = req.getParameter("name");
    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) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return res;
  }
}

使用建模方法保存/book

模型configmodel类

package com.lya.model;
import java.util.HashMap;
import java.util.Map;
public class ConfigModel {
  private Map<String, ActionModel> aMap = new HashMap<String, ActionModel>();
  public void push(ActionModel actionModel) {
    aMap.put(actionModel.getPath(), actionModel);
  }
  public ActionModel pop(String path) {
    return aMap.get(path);
  }
  public static void main(String[] args) throws Exception {
    ConfigModel configModel = ConfigModelFactory.build();
    ActionModel actionModel = configModel.pop("/loginAction");
    ForwardModel forwardModel = actionModel.pop("success");
    System.out.println(forwardModel.getPath());
  }
}

模型工厂configmodelFactory类

package com.lya.model;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/*
 * 
 * build/newinstance
 */
public class ConfigModelFactory {
  public static ConfigModel build(String xmlPath) throws Exception {
    ConfigModel configModel = new ConfigModel();
    InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath);
    SAXReader sr = new SAXReader();
    Document doc = sr.read(in);
    // System.out.println(doc.asXML());
    // configModel要有类容,就意味着actionmodel要有类容,然后放入到configmodel中去
    List<Element> actionEles = doc.selectNodes("/config/action");
    for (Element actionEle : actionEles) {
      // System.out.println(actionEle.asXML());
      ActionModel actionModel = new ActionModel();
      actionModel.setPath(actionEle.attributeValue("path"));
      actionModel.setType(actionEle.attributeValue("type"));
      // actionModel要有forwardModel,就意味着forwardmodel要有类容,然后放入到actionmodel中去
      List<Element> forwardEles = actionEle.selectNodes("forward");
      for (Element forwardEle : forwardEles) {
        System.out.println(forwardEle.asXML());
        ForwardModel forwardModel = new ForwardModel();
        forwardModel.setName(forwardEle.attributeValue("name"));
        forwardModel.setPath(forwardEle.attributeValue("path"));
        // 只有填写false才是转发,其它都为重定向
        // forwardModel.setRedirect(false);
        forwardModel.setRedirect(!"false".equals(forwardEle.attributeValue("redirect")));
        actionModel.push(forwardModel);
      }
      configModel.push(actionModel);
    }
    return configModel;
  }
  public static ConfigModel build() throws Exception {
    return build("/mvc.xml");
  }
  public static void main(String[] args) throws Exception {
    ConfigModelFactory.build();
  }
}

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <action path="/book" type="com.lya.web.BookAction">
    <forward name="list" path="/index2.jsp" redirect="false" />
    <forward name="tolist" path="/index2.jsp" redirect="true" />
  </action>
  <action path="/goods" type="com.lya.web.BookAction">
    <forward name="a" path="/index.jsp" redirect="false" />
    <forward name="b" path="/welcome.jsp" redirect="true" />
  </action>
</config>

2.优化Bookaction中我们使用req,resp跳转到指定的页面!(一行代码解决)

这里仍要注意:查看使用转发,增删改使用重定向(只会提交一次)。(会丢失路径)

思路:这里我们想Bookaction是继承action的,所以我们改变action中的代码。同过判断查看与增删改的返回,来执行是转发还是重定向。注意解决路径丢失问题:(丢失路径 = request.getContextPath()+ "/")

代码:放置在中央控制器中(通过中央控制器去调对应的请求)

Action action = (Action) Class.forName(type).newInstance();
        if(action instanceof ModelDriver) {
          ModelDriver md = (ModelDriver) action;
          Object bean = md.getModel();
          Map<String, String[]> parameterMap = request.getParameterMap();
//          BeanUtils---------设值到action中
          BeanUtils.populate(bean, parameterMap);
        }
        //execute------list/tolist 
        String execute = action.execute(request, response);
        ForwardModel ForwardModel = actionModel.pop(execute);
        if(ForwardModel!=null) {
          boolean redirect = ForwardModel.isRedirect();
          String path = ForwardModel.getPath();
          if(redirect) {//是重定向(丢失路径 + request.getContextPath()+ "/")
            response.sendRedirect(request.getContextPath()+ "/"+ path);
          }else {
            request.getRequestDispatcher(path).forward(request, response);
          }
        }

       

3.优化Bookaction中我们使用的new 1.对象 2.去get, 3.set 对象的属性,4.子控制器通用。

 

注意:实例对象在方法外面,通过构建ModelDrivel( 模型驱动接口(用来设置实体的值))用BookAction调用对应的方法getModel();在中央控制器中判断Action是否实现模型驱动接口,利用BeanUtils将值设置到Action中

Action action = (Action) Class.forName(type).newInstance();
        if(action instanceof ModelDriver) {
          ModelDriver md = (ModelDriver) action;
          Object bean = md.getModel();
          Map<String, String[]> parameterMap = request.getParameterMap();
//          BeanUtils---------设值到action中
          BeanUtils.populate(bean, parameterMap);

                       好了今天就分享到这!!!希望能够帮助到你的学习或工作!!!

目录
相关文章
|
2月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
2月前
|
前端开发 Java
【案例+源码】详解MVC框架模式及其应用
【案例+源码】详解MVC框架模式及其应用
154 0
|
4月前
|
设计模式 存储 前端开发
MVC 框架的主要问题是什么?
【8月更文挑战第30天】
96 0
|
6月前
|
JSON 前端开发 Java
【JavaEE进阶】 关于Spring MVC 响应
【JavaEE进阶】 关于Spring MVC 响应
63 3
|
6月前
|
安全 前端开发 测试技术
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
安全开发-PHP应用&模版引用&Smarty渲染&MVC模型&数据联动&RCE安全&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞
|
7月前
|
前端开发 Java Spring
Java Web ——MVC基础框架讲解及代码演示(下)
Java Web ——MVC基础框架讲解及代码演示
71 1
|
7月前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
90 1
|
7月前
|
设计模式 前端开发 网络协议
Java Web ——MVC基础框架讲解及代码演示(上)
Java Web ——MVC基础框架讲解及代码演示
57 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
56 0
|
7月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
212 0