自定义MVC框架(中)进阶版---详细讲解

简介: 自定义MVC框架(中)进阶版---详细讲解



一,自定义mvc的流程

  1. 用户发送请求到指定的 URL。
  2. 应用程序的路由器(Router)根据 URL 分发请求给对应的控制器。
  3. 控制器解析用户的输入,调用相应的模型和视图,并获取处理结果。
  4. 视图负责生成用户界面,并将处理结果展示给用户。
  5. 用户与视图进行交互,发送新的请求。
  6. 控制器再次处理新的请求,并返回结果给用户。

二,XML建模进行反射优化

2.1常见的优化方法

  1. 定义路由配置:将路由规则和URL与控制器的映射关系配置在XML文件中。这样可以避免在代码中硬编码路由规则,提高了代码的可维护性和灵活性。
  2. 定义视图配置:将视图相关的配置信息,如视图路径、模板引擎的配置等,放在XML文件中。这样可以使视图的配置更加集中和可配置化,方便扩展和管理。
  3. 定义模型配置:将模型的相关配置信息,如数据库连接、数据表映射等配置在XML文件中。这样可以使模型的配置更加灵活和易于管理,同时也降低了与数据库相关的代码依赖。
  4. 自定义注入配置:将依赖注入(DI)容器的配置信息放在XML文件中。通过配置XML文件中的依赖注入关系,可以实现灵活的控制器、模型和视图的注入,减少耦合度,提高代码的可测试性和可维护性。
  5. 定义拦截器配置:将拦截器的配置信息,如拦截的URL规则、拦截器的顺序等,放在XML文件中。这样可以方便地定义和管理拦截器链,实现各种应用场景下的权限控制、日志记录等功能。

2.2 xml建模反射优化案例:

首先定义一个xml配置文件

注意:该xml配置文件需要放到到跟目录中(如下图)包--New--Shurce Folder

本案例需要操作的XML文件:

本XML各属性名含义:

 action:

         path=""前端操作类名称

         type=""该类的路径名

 forward:

       name:方法返回名

       path:跳转的路径

        redirect:该结果集是否进行重定向

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <action path="/Order" type="com.LiuBing.framework.OrderAction">
    <forward name="failed" path="/reg.jsp" redirect="false" />
    <forward name="success" path="/login.jsp" redirect="true" />
  </action>
  <action path="/Book" type="com.LiuBing.framework.BookAction">
    <forward name="list" path="/res.jsp" redirect="false" />
    <forward name="tolist" path="/res.jsp" redirect="true" />
  </action>
</config>

中央控制器代码:

   前言:获取建模xml文件总容器ConFigModel,获取子容器actionmodel进行判断,判断xml配置文件中是否有前端所操作的类及对象,如果没有将会报出自定义异常action not config

如:

package com.LiuBing.framework;
/**
 * 中央控制器
 */
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
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.LiuBing.framework.model.ActionModel;
import com.LiuBing.framework.model.ConFigModel;
import com.LiuBing.framework.model.ConfigModelFactory;
import com.LiuBing.framework.model.ForwardModel;
@WebServlet("*.action")
public class DispatherServlet extends HttpServlet {
  // 定义一个map集合
  // public Map<String, Action> actionmap= new HashMap<String, Action>();
  private ConFigModel conFigModel;
  @Override
  public void init(ServletConfig config) 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 {
    doPost(req, resp);
  }
  @SuppressWarnings("rawtypes")
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String uri = req.getRequestURI();// 地址方法
    // 获取到相关的地址信息并过滤
    uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
    // 将地址保存到action
    // Action action = actionmap.get(uri);
    // 获取配置文件中action
    ActionModel actionmodel = conFigModel.pop(uri);
    // 判断action是否为空
    if (actionmodel == null)
      // 为空提示语句
      throw new RuntimeException("action not config");
    // 不为空就获取到type路径(想进行哪个的业务操作路径)
    String type = actionmodel.getType();
    Action action;
    try {
      // 获取反射需要操作的类类
      action = (Action) Class.forName(type).newInstance();
      //判断子容器BookAction有无实现ModelDriver 模型驱动接口接口
       if(action instanceof ModelDriver) {//默认实现了该接口
         ModelDriver md = (ModelDriver) action;
         Object bean = md.getModel();
         BeanUtils.populate(bean, req.getParameterMap());
       }
      // Action的res返回值
      String res = action.execut(req, resp);
      //根据Action的返回值  该方法是重定向还是转发 
      ForwardModel forwardmodel = actionmodel.pop(res);
      //判断如果forwardmodel模型中有数据
      if(forwardmodel!=null) {
        //前端操作数据是转发还是重定向 true false 
        boolean redirect = forwardmodel.isRedirect();
        //转发的页面
        String path = forwardmodel.getPath();
        //转发
        if(redirect) {
          resp.sendRedirect(path);
        }else {
          //重定向
          req.getRequestDispatcher(path).forward(req, resp);
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

三,优化方法结果集调用跳转

3.1大概步骤:

        在子类对象相对应的操作返回类型例如BookAction返回类型定义为String类型,并在中央控制器中接受子类的方法返回值,中央控制器中判断redirect重定向,最后进行xml文件的相对应的配置

子控制器代码:

package com.LiuBing.framework;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.LiuBing.entity.Book;
public class BookAction extends Action implements ModelDriver<Book> {
  Book book = new Book();
  public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("进入的是增加BookaddServlet....");
    request.setAttribute("content", "崽崽");
    response.sendRedirect("res.jsp");
    return "tolist";
  }
  public String del(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("进入的是删除BookadelServlet....");
    request.setAttribute("content", "崽崽");
    response.sendRedirect("res.jsp");
    return "tolist";
  }
  public String upd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("进入的是修改BookupdServlet....");
    request.setAttribute("content", "崽崽");
    response.sendRedirect("res.jsp");
    return "tolist";
  }
  public String list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("进入的是查询BooklistServlet....");
    request.setAttribute("content", "崽崽");
    return "list";
  }
  @Override
  public Book getModel() {
    return book;
  }
}

中央控制器代码:

// Action的res返回值
      String res = action.execut(req, resp);
      //根据Action的返回值  该方法是重定向还是转发 
      ForwardModel forwardmodel = actionmodel.pop(res);
      //判断如果forwardmodel模型中有数据
      if(forwardmodel!=null) {
        //前端操作数据是转发还是重定向 true false 
        boolean redirect = forwardmodel.isRedirect();
        //转发的页面
        String path = forwardmodel.getPath();
        //转发
        if(redirect) {
          resp.sendRedirect(path);
        }else {
          //重定向
          req.getRequestDispatcher(path).forward(req, resp);
        }
      }
配置文件代码按本案例配置文件操作即可

最后运行结果:

进行增删改操作只会显示跳转成功,而查询所有会显示相对应的内容,这是因为增删改是重定向而查询是转发

四,优化参数的封装

4.1 前言:

    在我们进行接受前端带过来的参数,往往会带很多参数在子控制器中进行遍历及封装加到实体中,这样会很麻烦的大大降低了代码效率,那有什么办法在进行这一步进行一个改善呢?有!模型驱动接口---连接模型和其他系统或应用程序的接口。它允许使用模型的输出来驱动和控制其他系统的行为。

定义一个模型驱动接口

在中央控制器中,进行判断子控制器是否继承了模型驱动接口, BeanUtils.populate方法以键值对形式存储该被反射的类

模型驱动接口:

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

中央控制器判断代码:

Action action;
    try {
      // 获取反射需要操作的类类
      action = (Action) Class.forName(type).newInstance();
      //判断子容器BookAction有无实现ModelDriver 模型驱动接口接口
       if(action instanceof ModelDriver) {//默认实现了该接口
         ModelDriver md = (ModelDriver) action;
         Object bean = md.getModel();//哪个继承了模型驱动接口
         BeanUtils.populate(bean, req.getParameterMap());//映射到该方法中  键值对形式
       }

泛型指定子控制器实体类。最后在子控制器中实现模型驱动接口实现其中的方法即可

目录
相关文章
|
2月前
|
前端开发 Java 程序员
从零基础手写Spring MVC框架,准备好进阶程序员了吗?
我们程序员大部分人都是野路子,不懂什么叫代码规范。写了一个月的代码,最后还得其他老司机花3天时间重构,相信大部分老司机都很头疼看新手的代码。
25 1
|
3月前
|
设计模式 前端开发 JavaScript
浅谈MVC、MVP、MVVM框架模式
浅谈MVC、MVP、MVVM框架模式
30 0
|
4月前
|
前端开发 数据库 Python
Python Web 开发: 解释 Django 框架的 MVC 架构是什么?
Python Web 开发: 解释 Django 框架的 MVC 架构是什么?
|
4月前
|
存储 前端开发 Java
Spring基础篇:MVC框架整合
Spring基础篇:MVC框架整合
|
3月前
|
Java 数据库连接 Maven
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
|
17天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南
|
24天前
|
前端开发 JavaScript Java
MVC框架:SpringMVC(三)
MVC框架:SpringMVC
30 0
|
24天前
|
JSON 前端开发 JavaScript
MVC框架:SpringMVC(二)
MVC框架:SpringMVC
35 0
|
24天前
|
前端开发 Java 应用服务中间件
MVC框架:SpringMVC(一)
MVC框架:SpringMVC
59 0
|
2月前
|
JSON 前端开发 Java
【JavaEE进阶】 关于Spring mvc 响应
【JavaEE进阶】 关于Spring mvc 响应