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

目录

前言

自定义MVC实现

1. 导入XML配置文件

 2. 导入XML解析建模

3. 优化中央控制器

3.1 修改DisPathServlet中init初始化方法

3.2 修改ActionServlet逻辑处理流程

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

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

4. 反射赋值

4.1 创建接口DriverModel

4.2 实现接口类

4.3  反射对象赋值


前言

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

自定义MVC实现

1. 导入XML配置文件



	
		
		
	
	
		
		
	

将其部署到Source Folder文件中

自定义MVC引用XML配置文件实现_第1张图片

 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 
 */
public interface ModelDriver {
	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 = new Book();
	
	@Override
	public Book getModel() {
		// TODO Auto-generated method stub
		return book;
	}
 
	public String load(HttpServletRequest req, HttpServletResponse resp) {
		//获取所有的参数
		Map 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());
			}

你可能感兴趣的:(笔记)