目录
这篇 自定义MVC框架(框架实现)就介绍到这里了,欢迎大佬来提建议哦!!!!
一.什么是自定义MVC框架
MVC自定义框架是指基于MVC模式而构建的自定义框架,用于开发和管理特定的Web应用程序。通过自定义框架,开发者可以按照自己的需求和约定构建自己的应用程序结构,并实现对模型、视图和控制器的定制和扩展。
自定义框架通常提供了一系列工具和库,用于简化开发过程、处理路由和请求、管理数据和视图的输出等。开发者可以根据自己的项目需求,选择或编写适合的模块和扩展来拓展框架的功能。这样,开发者可以更加高效和灵活地构建符合自己需求的应用程序。
二.搭建自定义MVC框架
要自定义搭建一个基于MVC模式的框架,可以按照以下步骤进行:
定义目录结构:创建一个合适的目录结构,用于组织框架的各个组件和功能模块。通常包括模型、视图、控制器、配置文件、路由器等。
设计模型(Model):根据应用程序的需求,设计和实现模型层的代码。模型负责处理数据的获取、存储和操作。可以根据框架需求,选择相应的数据库连接方式、ORM(对象关系映射)工具等。
设计视图(View):设计和实现视图层的代码,用于呈现数据给用户并处理用户界面的逻辑。视图通常由HTML、CSS和客户端脚本组成。
设计控制器(Controller):设计和实现控制器层的代码,处理用户的请求并协调模型和视图之间的交互。控制器负责接收和解析用户的请求,调用相应的模型进行数据处理,并将最终结果传递给视图进行展示。
设计路由器(Router):设计和实现路由器的代码,用于将用户的请求映射到相应的控制器和动作。路由器根据不同的URL和请求方法,将请求分发给对应的控制器。
设计配置文件:创建一个配置文件,用于存储框架的各种配置参数,例如数据库连接信息、路由规则、密钥等。这样可以使框架更灵活和可配置。
编写框架核心代码:实现框架的核心代码,包括加载配置、解析路由、初始化控制器等。确保框架的基本功能和运行机制正常。
提供扩展机制:考虑到不同项目的需求差异,提供一些扩展机制,允许开发者根据需要添加自定义的模块和功能。
编写示例应用:编写一个简单的示例应用程序,演示如何使用框架进行开发。这可以作为其他开发者上手和理解框架的参考。
测试和优化:进行测试和调试,确保框架的稳定性和性能。根据反馈和需求进行优化和改进。
最后,你需要考虑到每个组件的互相沟通和协作,并根据实际应用需求进行完善和迭代。搭建一个自定义的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框架(框架实现)就介绍到这里了,欢迎大佬来提建议哦!!!!