自定义MVC引用XML配置文件实现

简介: 自定义MVC引用XML配置文件实现

前言

     在这篇 自定义MVC框架思想 中我已详细描述了工作原理及流程,本篇主要在此基础上继续做出优化,实现步骤如下:

自定义MVC实现

1. 导入XML配置文件

<?xml version="1.0" encoding="UTF-8"?>
<config>
  <action path="/order" type="com.xzs.servlet.OrderAction">
    <forward name="success" path="/index.jsp" redirect="true" />
    <forward name="failed" path="/register.jsp" redirect="false" />
  </action>
  <action path="/book" type="com.xzs.servlet.BookAction">
    <forward name="List" path="/book.jsp" redirect="false" />
    <forward name="toList" path="/index.jsp" redirect="true" />
  </action>
</config>

将其部署到Source Folder文件中

2. 导入XML解析建模

这里就不一一详细解说了,可以去 XML建模 中了解详细建模实例。

3. 优化中央控制器

3.1 修改DisPathServlet中init初始化方法

在DisPathServlet的init方法中将原有Map集合方式替换成XML建模方式  

// 通过xml建模方法进行储存
    private ConfigModel configModel;
    @Override
    public void init() throws ServletException {
        /**
         * 初始化存值就是给每个施工员根据施工证进行存档:
         */
        try {
            // configModel包含了所有的子控制器
            configModel = ConfigModelFactory.build();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3.2 修改ActionServlet逻辑处理流程

根据请求路径名获取ActionModel

这里如果查不到指定对象,请认真检查xml文件的配置,以及截取的内容是否与xml配置相同

/**
     * 获取请求路径
     */
    String uri = request.getRequestURI();
    // 截取book
    uri = uri.substring(uri.lastIndexOf("/"), uri.lastIndexOf("."));
    // 要通过uri->> /book,在configModel对象中找
    ActionModel actionModel = configModel.pop(uri);
    // 判断没找对象等于空就抛出异常
    if (actionModel == null)
      throw new RuntimeException("action not config");
    /**
     * 获取config文件中action标签的type属性值
     * type指java类
     * com.ycxw.servlet.BookAction
     */
    String type = actionModel.getType();

3.3  通过反射机制实例化子控制器类

package com.xzs.framework;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 子控制器(action) 处理浏览器请求的类
 * 
 * @author 
 *
 * 2023年6月29日 下午8:30:32
 */
public class Action {
  public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 获取methodName值,这里指前端点击功能传来的方法名
    String methodName = request.getParameter("methodName");
    //定义一个变量来保存返回值
    String res = "";
    /**
     * this--->BookAction/BlogAction/PermissionAction...可能是很多对象
     * 所以需要通过反射找到对象带request,response参数的methidName方法
     */
    Method m = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
    m.setAccessible(true);
    // 动态调用其方法
    res = (String) m.invoke(this, request, response);
    return res ;
  }
}

3.4 中央控制器将请求委托给子控制器处理

Action instance = (Action) Class.forName(type).newInstance();
// 业务代码执行后返回值
String execute = instance.execute(request, response);

3.5 根据请求结果码跳转页面

        // 通过返回值拿到,该方法结果是重定向还是转发,还是跳转哪个页面
      ForwardModel forwardModel = actionModel.pop(execute);
      if (forwardModel != null) {
        // 获取forwardModel是否从定向值
        boolean redirect = forwardModel.isRedirect();
        /**
         * 获取xml元素path值   
         */
        String path = forwardModel.getPath();
        // 判断是否为重定向
        if (redirect) {
          response.sendRedirect(request.getContextPath() + "/" + path);
        } else {
          request.getRequestDispatcher(path).forward(request, response);
        }
      }

4. 反射赋值

4.1 创建接口DriverModel

package com.xzs.framework;
/**
 * 模型驱动接口
 * Book book = new Book();
 * @author 
 *
 * @param <T>
 */
public interface ModelDriver<T> {
  T getModel();
}

4.2 实现接口类

针对需要进行反射赋值的具体子控制器类,实现该接口DriverModel。

package com.xzs.servlet;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.xzs.entity.Book;
import com.xzs.framework.Action;
import com.xzs.framework.ModelDriver;
/**
 * 施工类 继承子控制器
 * 
 * @author 
 *
 * @2023年6月29日 下午8:32:59
 */
public class BookAction extends Action implements ModelDriver<Book>{
  //创建表对应的属性对象
  Book book = new Book();
  @Override
  public Book getModel() {
    // TODO Auto-generated method stub
    return book;
  }
  public String load(HttpServletRequest req, HttpServletResponse resp) {
    //获取所有的参数
    Map<String, String[]> map = req.getParameterMap();
    System.out.println("Book查询的业务逻辑");
    try {
      resp.sendRedirect("index.jsp");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "List";
  }
  public String query(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("Book查询的业务逻辑");
    try {
      resp.sendRedirect("index.jsp");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "List";
  }
  public String edit(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("Book修改的业务逻辑");
    try {
      resp.sendRedirect("index.jsp");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "toList";
  }
  public String delete(HttpServletRequest req, HttpServletResponse resp) {
    System.out.println("Book删除的业务逻辑");
    try {
      resp.sendRedirect("index.jsp");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "toList";
  }
  public String add(HttpServletRequest req, HttpServletResponse resp) throws Exception {
    System.out.println("Book新增的业务逻辑");
    req.getRequestDispatcher("index.jsp").forward(req, resp);
    return "toList";
  }
}

只要实现了DriverModel接口,则必须要对实体类进行初始化,并在getModel()方法中返回实例化后的对象。

4.3  反射对象赋值

/**
     * 获取config文件中action标签的type属性值
     * type指java类
     * com.ycxw.servlet.BookAction
     */
    String type = actionModel.getType();
    // 通过反射创建对象
    Action instance;
    try {
      instance = (Action) Class.forName(type).newInstance();
      // 判断bookAction有没有实现ModelDriver接口
      if (instance instanceof ModelDriver) {
        // 向下转型获取接口方法
        ModelDriver md = (ModelDriver) instance;
        Object bean = md.getModel();
        // 把获取的参数保存到该对象中
        BeanUtils.populate(bean, request.getParameterMap());
      }


相关文章
|
4月前
|
XML Java 数据库连接
MyBatis入门——MyBatis XML配置文件(3)
MyBatis入门——MyBatis XML配置文件(3)
56 6
|
3月前
|
存储 缓存 分布式计算
Hadoop配置文件core-site.xml
【7月更文挑战第17天】
117 2
Hadoop配置文件core-site.xml
|
3月前
|
XML 分布式计算 资源调度
Hadoop配置文件mapred-site.xml
【7月更文挑战第18天】
145 7
|
3月前
|
存储 机器学习/深度学习 分布式计算
Hadoop配置文件hdfs-site.xml
【7月更文挑战第17天】
107 5
|
2月前
logback.xml 配置文件
logback.xml 配置文件
15 0
|
3月前
|
分布式计算 资源调度 Hadoop
Hadoop配置文件yarn-site.xml
【7月更文挑战第18天】
145 3
|
3月前
|
XML 开发工具 数据格式
自定义 DSL 流程图(含XML 描述邮件,XML 描述流程图)
自定义 DSL 流程图(含XML 描述邮件,XML 描述流程图)
28 0
自定义 DSL 流程图(含XML 描述邮件,XML 描述流程图)
|
4月前
|
Java Maven
Maven自用配置文件(settings.xml)
Maven自用配置文件(settings.xml)
438 0
|
4月前
|
缓存 Java
ehcache.xml配置文件详解
ehcache.xml配置文件详解
|
5月前
|
XML Java 数据库连接
Javaweb之Mybatis的XML配置文件的详细解析
Javaweb之Mybatis的XML配置文件的详细解析
54 0