自定义MVC框架(框架实现)

本文介绍了自定义MVC框架的概念,详细阐述了搭建框架的步骤,包括模型、视图、控制器的设计,以及路由器和配置文件的创建。重点讨论了利用XML配置进行建模和反射优化,以提高框架的灵活性和效率。文中还提供了Action和DispatchServlet的代码示例,展示了如何处理请求和响应。
摘要由CSDN通过智能技术生成

目录

一.什么是自定义MVC框架

二.搭建自定义MVC框架

三.自定义MVC框架优化实现

3.1利用xml建模反射优化

这篇 自定义MVC框架(框架实现)就介绍到这里了,欢迎大佬来提建议哦!!!!


一.什么是自定义MVC框架

MVC自定义框架是指基于MVC模式而构建的自定义框架,用于开发和管理特定的Web应用程序。通过自定义框架,开发者可以按照自己的需求和约定构建自己的应用程序结构,并实现对模型、视图和控制器的定制和扩展。

自定义框架通常提供了一系列工具和库,用于简化开发过程、处理路由和请求、管理数据和视图的输出等。开发者可以根据自己的项目需求,选择或编写适合的模块和扩展来拓展框架的功能。这样,开发者可以更加高效和灵活地构建符合自己需求的应用程序。

二.搭建自定义MVC框架

要自定义搭建一个基于MVC模式的框架,可以按照以下步骤进行:

  1. 定义目录结构:创建一个合适的目录结构,用于组织框架的各个组件和功能模块。通常包括模型、视图、控制器、配置文件、路由器等。

  2. 设计模型(Model):根据应用程序的需求,设计和实现模型层的代码。模型负责处理数据的获取、存储和操作。可以根据框架需求,选择相应的数据库连接方式、ORM(对象关系映射)工具等。

  3. 设计视图(View):设计和实现视图层的代码,用于呈现数据给用户并处理用户界面的逻辑。视图通常由HTML、CSS和客户端脚本组成。

  4. 设计控制器(Controller):设计和实现控制器层的代码,处理用户的请求并协调模型和视图之间的交互。控制器负责接收和解析用户的请求,调用相应的模型进行数据处理,并将最终结果传递给视图进行展示。

  5. 设计路由器(Router):设计和实现路由器的代码,用于将用户的请求映射到相应的控制器和动作。路由器根据不同的URL和请求方法,将请求分发给对应的控制器。

  6. 设计配置文件:创建一个配置文件,用于存储框架的各种配置参数,例如数据库连接信息、路由规则、密钥等。这样可以使框架更灵活和可配置。

  7. 编写框架核心代码:实现框架的核心代码,包括加载配置、解析路由、初始化控制器等。确保框架的基本功能和运行机制正常。

  8. 提供扩展机制:考虑到不同项目的需求差异,提供一些扩展机制,允许开发者根据需要添加自定义的模块和功能。

  9. 编写示例应用:编写一个简单的示例应用程序,演示如何使用框架进行开发。这可以作为其他开发者上手和理解框架的参考。

  10. 测试和优化:进行测试和调试,确保框架的稳定性和性能。根据反馈和需求进行优化和改进。

 最后,你需要考虑到每个组件的互相沟通和协作,并根据实际应用需求进行完善和迭代。搭建一个自定义的MVC框架需要一定的知识和经验,同时也要对底层的技术原理有一定的了解。如果你是初学者或时间有限,也可以考虑使用已有的成熟框架,以节省开发时间和精力。

三.自定义MVC框架优化实现

3.1利用xml建模反射优化

创建配置文件:

<?xml version="1.0" encoding="UTF-8"?>

<config>

	<action path="/order" type="com.junlinyi.servlet.OrderAction">
		<!-- forward标签:没有子标签; name:字符串,同一action标签下的forward标签name值不能相同 ; path:以/开头的字符串 
			redirect:只能是false|true,允许空,默认值为false -->

		<forward name="failed" path="/reg.jsp" redirect="false" />
		<forward name="success" path="/login.jsp" redirect="true" />
	</action>

	<action path="/book" type="com.junlinyi.servlet.BookAction">
		<forward name="failed" path="/login.jsp" redirect="false" />
		<forward name="success" path="/main.jsp" redirect="true" />
	</action>
	
</config>

分析:action path: (/)加上你的写的项目类名    forward path:要跳转的页面   redirect:重定向判断    type:项目的路径

注意: 如果你没有配置文件就会报错,下列是展示图:报action not config 就是没有配置文件

 

Action :

package com.junlinyi.framework;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 子控制器
 * 真正做事,处理浏览器发送请求的类
 * @author: 君临沂
 *
 */
public class Action {
	protected String execute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String methodName = req.getParameter("methodName");
//		返回值
		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) {
			e.printStackTrace();
		}
		return res;
		
	}
}

 DispathServlet:

package com.junlinyi.framework;

import java.io.IOException;
import java.util.HashMap;
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.junlinyi.model.ActionModel;
import com.junlinyi.model.ConfigModel;
import com.junlinyi.model.ConfigModelFactory;
import com.junlinyi.model.ForwardModel;
import com.junlinyi.servlet.BookAction;
import com.junlinyi.servlet.OrderAction;
/**
 * 中央控制器
 * @author: 君临沂
 *
 */
@WebServlet("*.action")
public class DispathServlet extends HttpServlet{
//		public Map<String,Action> actionMap=new HashMap<String, Action>();
//		原来所有的子控器是放到map集合中,
//	现在所有的子控制器在mvc.xml中,
//	其实就是放到configModel
	private ConfigModel configModel;
		@Override
		public void init() 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 {
			this.doPost(req, resp);
		}
		@Override
		protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			String uri = req.getRequestURI();
			uri=uri.substring(uri.lastIndexOf("/"),
					uri.lastIndexOf("."));
//			Action action = actionMap.get(uri);
//			通过uri=/book,在configModel对象中找
			ActionModel actionModel = configModel.pop(uri);
//			判断
			if(actionModel == null)
				throw new RuntimeException("action not config");//你没有配置
//			拿type值 com.junlinyi.servlet.BookAction 
			String type = actionModel.getType();
//			反射实例化 BookAction
			Action action;
			try {
				action = (Action) Class.forName(type).newInstance();
//				BookAction有没有实现ModelDriver接口
				if(action instanceof ModelDriver) {
					ModelDriver md=(ModelDriver) action;
					Object bean = md.getModel();
					Map<String, String[]> map = req.getParameterMap();
					BeanUtils.populate(bean, map);
				}
//				具体业务代码执行后的返回值 add/del/upd/list的返回值===》list /tolist
				String res = action.execute(req, resp);
//				通过返回值拿到,该方法结果是重定向还是转发,还是跳转那个页面
				ForwardModel forwardModel = actionModel.pop(res);
				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();
			}
		}
}

 ConfigModelFactory:

package com.junlinyi.model;

import java.io.InputStream;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 23种设计模式--工厂模式--创建型模式
 * @author: 君临沂
 *
 */
public class ConfigModelFactory {
		public static ConfigModel build() throws Exception {
			ConfigModel configModel=new ConfigModel();
			
			InputStream is = ConfigModelFactory.class.getResourceAsStream("/mvc.xml");
			SAXReader sa=new SAXReader();
			Document doc = sa.read(is);
//			System.out.println(doc.asXML());
			List<Element> actionEls = doc.selectNodes("/config/action");
			for (Element actionEl  : actionEls) {
//				System.out.println(actionEl.asXML()); 
			ActionModel actionModel=new ActionModel();
			actionModel.setPath(actionEl.attributeValue("path"));
			actionModel.setType(actionEl.attributeValue("type"));
			
			List<Element> forwardEls = doc.selectNodes("/config/action/forward");
			for (Element forwardEl  : forwardEls) {
				System.out.println(forwardEl.asXML()); 
				ForwardModel forwardModel=new ForwardModel();
				forwardModel.setName(forwardEl.attributeValue("name"));
				forwardModel.setPath(forwardEl.attributeValue("path"));
//				只有填false才能转发,其它都是重定向
				forwardModel.setRedirect(!"false".equals(forwardEl.attributeValue("redirect")));
				
				actionModel.push(forwardModel);
			}
			configModel.push(actionModel);			
			}
			return configModel;
		}
		public static void main(String[] args) throws Exception {
			ConfigModelFactory.build();
		}
}

 ForwardModel:

package com.junlinyi.model;

/**
 * 
 * @author: 君临沂
 *
 */
public class ForwardModel {
	private String name;
	private String path;
	private boolean 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;
	}
	
	
	
}

 BookAction:

package com.junlinyi.servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.junlinyi.entity.Book;
import com.junlinyi.framework.Action;
import com.junlinyi.framework.ModelDriver;
/**
 * BookAction类
 * @author: 君临沂
 *要有表对应的类属性对象  Book book
 *获取所有的参数值  req.getParameterMap();
 *将参数值封装到表对应的对象中
 *要做到所有的子控制器通用
 */
public  class BookAction extends Action implements ModelDriver<Book>{
	private Book book=new Book();
	public  String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		Map<String, String[]> map = req.getParameterMap();
		System.out.println("恭喜你进入add....");
		req.setAttribute("hjh","小黑包来了哦");
//		resp.sendRedirect("res.jsp");
		return "tolist";
	}
	
	public  String del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("恭喜你进入del....");
		req.setAttribute("hjh","小黑包来了哦");
//		resp.sendRedirect("res.jsp");
		return "tolist";
	}
	
	public  String upd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("恭喜你进入upd....");
		req.setAttribute("hjh","小黑包来了哦");
//		resp.sendRedirect("res.jsp");
		return "tolist";
	}
	
	public  String list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("恭喜你进入list....");
		req.setAttribute("hjh","小黑包来了哦");
//		req.getRequestDispatcher("res.jsp").forward(req, resp);
		return "list";
	}

	@Override
	public Book getModel() {
		return book;
	}
}

index.jsp :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
常识:查询必然转发,增删改使用重定向
弊端:中央控制器的action容器加载不可以灵活配置<hr>
<a href="book.action?methodName=add">增加</a>
<a href="book.action?methodName=del">删除</a>
<a href="book.action?methodName=upd">修改</a>
<a href="book.action?methodName=list">查询</a>
</body>
</html>

res.jsp: ${hjh }再加点内容(方便自己测试)

结果图展示: 

 

 

 

 正好对应这个常识:查询必然转发,增删改使用重定向

这篇 自定义MVC框架(框架实现)就介绍到这里了,欢迎大佬来提建议哦!!!!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值