自定义mvc

2023-11-02

1. 什么是MVC
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,
它是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码。

 

2. MVC结构

V
jsp/ios/android
C
servlet/action
M
实体域模型(名词)
过程域模型(动词)


注1:不能跨层调用
注2:只能出现由上而下的调用

 

 


3. 自定义MVC工作原理图

 

 

 

具体代码实现如下(我们就以一个简单计算器作为示例)

1.首先需要导入需要用到的jar包

2.对xml文件进行建模(工厂模式)

<?xml version="1.0" encoding="UTF-8"?>
	<!--
		config标签:可以包含0~N个action标签
	-->
<config>
	<!--
		action标签:可以饱含0~N个forward标签
		path:以/开头的字符串,并且值必须唯一 非空
		type:字符串,非空
	-->
	
	<action path="/Cal" type="com.hmc.web.AddCalAction">
		<forward name="res" path="/res.jsp" redirect="false" />
	</action>
</config>

建模代码

 ForwardModel

package com.hmc.framework;

import java.io.Serializable;

/**
 * 用来描述forward标签
 * @author Administrator
 *
 */
public class ForwardModel implements Serializable {

	private static final long serialVersionUID = -8587690587750366756L;

	private String name;
	private String path;
	private String 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 String getRedirect() {
		return redirect;
	}

	public void setRedirect(String redirect) {
		this.redirect = redirect;
	}

}

  

   ActionModel

package com.hmc.framework;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 用来描述action标签
 * @author Administrator
 *
 */
public class ActionModel implements Serializable{

	private static final long serialVersionUID = 6145949994701469663L;
	
	private Map<String, ForwardModel> forwardModels = new HashMap<String, ForwardModel>();
	
	private String path;
	
	private String type;
	
	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void put(ForwardModel forwardModel){
		forwardModels.put(forwardModel.getName(), forwardModel);
	}
	
	public ForwardModel get(String name){
		return forwardModels.get(name);
	}
	
}

  

  ConfigModel

package com.hmc.framework;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 用来描述config标签
 * @author Administrator
 *
 */
public class ConfigModel implements Serializable{

	private static final long serialVersionUID = -2334963138078250952L;
	
	private Map<String, ActionModel> actionModels = new HashMap<String, ActionModel>();
	
	public void put(ActionModel actionModel){
		actionModels.put(actionModel.getPath(), actionModel);
	}
	
	public ActionModel get(String name){
		return actionModels.get(name);
	}
	
}

  

 ConfigModelFactory

package com.hmc.framework;

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

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

public class ConfigModelFactory {
	private ConfigModelFactory() {

	}

	private static ConfigModel configModel = null;

	public static ConfigModel newInstance() throws Exception {
		return newInstance("mvc.xml");
	}

	/**
	 * 工厂模式创建config建模对象
	 * 
	 * @param path
	 * @return
	 * @throws Exception
	 */
	public static ConfigModel newInstance(String path) throws Exception {
		if (null != configModel) {
			return configModel;
		}

		ConfigModel configModel = new ConfigModel();
		InputStream is = ConfigModelFactory.class.getResourceAsStream(path);
		SAXReader saxReader = new SAXReader();
		Document doc = saxReader.read(is);
		List<Element> actionEleList = doc.selectNodes("/config/action");
		ActionModel actionModel = null;
		ForwardModel forwardModel = null;
		for (Element actionEle : actionEleList) {
			 actionModel = new ActionModel();
			actionModel.setPath(actionEle.attributeValue("path"));
			actionModel.setType(actionEle.attributeValue("type"));
			List<Element> forwordEleList = actionEle.selectNodes("forward");
			for (Element forwordEle : forwordEleList) {
				forwardModel = new ForwardModel();
				forwardModel.setName(forwordEle.attributeValue("name"));
				forwardModel.setPath(forwordEle.attributeValue("path"));
				forwardModel.setRedirect(forwordEle.attributeValue("redirect"));
				actionModel.put(forwardModel);
			}

			configModel.put(actionModel);
		}

		return configModel;
	}
	
	public static void main(String[] args) {
		try {
			ConfigModel configModel = ConfigModelFactory.newInstance();
			ActionModel actionModel = configModel.get("/loginAction");
			ForwardModel forwardModel = actionModel.get("failed");
			System.out.println(actionModel.getType());
			System.out.println(forwardModel.getPath());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

  

 

3.编写一个中央控制器(DispatcherServlet)

package com.hmc.framework;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
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 org.eclipse.jdt.internal.compiler.env.ICompilationUnit;

import com.hmc.web.AddCalAction;


/**
 * 中央控制器
 *   作用: 接受请求,通过请求寻找处理请求对应的子控制器。
 * @author 
 *
 */

public class DispatcherServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//private Map<String , IAction> actionMap = new HashMap<>();
	
	//在configModel对象包含了所有的子控制信息
	private ConfigModel configModel;
	
	
	public void init() {
	//	actionMap.put("/addCal", new AddCalAction());
		try {
			
			String xmlPath=this.getInitParameter("xmlPath");
		
			if(xmlPath==null|| "".equals(xmlPath)) {
				configModel=ConfigModelFactory.newInstance();
				
			}else {
				configModel=ConfigModelFactory.newInstance(xmlPath);
			
				
			}
		   
		 } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
		
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		init();
		String url= request.getRequestURI();
//		/***/addCal.action
		url = url.substring(url.lastIndexOf("/"), url.lastIndexOf("."));
//		IAction action = actionMap.get(url);
		ActionModel actionModel = configModel.get(url);
//		if(actionModel ==null) {
//		throw	new RuntimeException("你没有配置action标签,找不到对应的子控制器处理浏览器发送的请求");
//		}
	 try {
		
		 
		Action action=(Action) Class.forName(actionModel.getType()).newInstance();
	    //action就是com.zking.web.CalAction
		if(action instanceof ModelDrivern) {
	    	ModelDrivern modelDrivern=(ModelDrivern)action;
	    	//此时的model的所有属性值都是null的
	    	Object model = modelDrivern.getModel();
	        BeanUtils.populate(model, request.getParameterMap());
	    	
	    	//我们可以将request.getParameterMap();的值通过反射的方式将其塞进model实例中
//	    	Map<String, String[]> parameterMap = request.getParameterMap();
//	    	Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
//		   Class<? extends Object> clz = model.getClass();
//	    	for (Entry<String, String[]> entry : entrySet) {
//		    Field field = clz.getField(entry.getKey());
//		   field.setAccessible(true);   
//		   field.set(model, entry.getValue());
//		}
		}
		
		
		
		//返回码
		String code = action.execute(request, response);
	    ForwardModel forwardModel = actionModel.get(code);
	   if(forwardModel!=null) {
		   String jspPath = forwardModel.getPath();
	      if("false".equals(forwardModel.getRedirect())) {
	    	  //做转发的处理
	    	  request.getRequestDispatcher(jspPath).forward(request, response);
	      }
	      else {
	    	  response.sendRedirect(request.getContextPath()+jspPath);
	      }
	   }
	 } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
//		try {
//			action.execute(req, resp);
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		
	}
	
	
	
}

  

 

编写子控制器接口

Action

package com.hmc.framework;

import java.io.IOException;

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

/**
 * 子控制器
 *   作用:用来直接处理浏览器发送过来的请求。
 * @author 
 *
 */
public interface Action {
	
 String execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, Exception;
 
 
}

 编写模型驱动接口ModelDrivern

package com.hmc.framework;

/**
 * 模型驱动接口
 * 作用是将jsp所有传递过来的参数以及参数值自动封装到浏览器所要操作的实体类中
 * @author Administrator
 *
 */
public interface ModelDrivern<T> {
  T getModel();
}

  增强版的子控制器(ActionSupport)实现上面的子控制器(Action)

package com.hmc.framework;

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 增强版的子控制器
 * 原来的子控制器只能处理一个用户请求
 * 作用:
 * 将一组相关的操作放到一个Action中
 * @author Administrator
 *
 */
public class ActionSupport implements Action{

	@Override
	public final String execute(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException, Exception {
     String menthodName=request.getParameter("menthodName");
	 //this值的是CalAction它的一个类实例
     String code=null;
     Method m=this.getClass().getDeclaredMethod(menthodName,HttpServletRequest.class,HttpServletResponse.class);
	 m.setAccessible(true);	
     code = (String) m.invoke(this,request,response);
		
		return code;
	}

}

  编写业务逻辑类CalAction

package com.hmc.web;

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

import com.hmc.entity.Cal;
import com.hmc.framework.ActionSupport;
import com.hmc.framework.ModelDrivern;

public class CalAction extends ActionSupport implements ModelDrivern<Cal>{
   private Cal cal=new Cal();

	public String add(HttpServletRequest request, HttpServletResponse response) throws Exception, Exception {	
//		String num1=request.getParameter("num1");
//		String num2=request.getParameter("num2");
		//Call cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
		request.setAttribute("res", cal.getNum1()+cal.getNum2());
		return "res";
	}

	public String minus(HttpServletRequest request, HttpServletResponse response) throws Exception, Exception {	
//		String num1=request.getParameter("num1");
//		String num2=request.getParameter("num2");
		//Call cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
		request.setAttribute("res", cal.getNum1()-cal.getNum2());
		return "res";
	}
	
	public String multiply(HttpServletRequest request, HttpServletResponse response) throws Exception, Exception {	
//		String num1=request.getParameter("num1");
//		String num2=request.getParameter("num2");
		//Call cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
		request.setAttribute("res", cal.getNum1()*cal.getNum2());
		return "res";
	}
	
	public String divided(HttpServletRequest request, HttpServletResponse response) throws Exception, Exception {	
//		String num1=request.getParameter("num1");
//		String num2=request.getParameter("num2");
		//Call cal=new Cal(Integer.valueOf(num1),Integer.valueOf(num2));
		request.setAttribute("res", cal.getNum1()/cal.getNum2());
		return "res";
	}
	
	
	@Override
	public Cal getModel() {
		// TODO Auto-generated method stub
		return cal;
	}

	
	
}

  

   以上就是自定义mvc的代码实现,下面看下演示效果

建一个jsp文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function doSub(num){
	if(num == 1){
		calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=add";
	}
	else if(num==2){
		calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=minus";
	}
	else if(num==3){
		calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=multiply";
	}
	else if(num==4){
		calForm.action="${pageContext.request.contextPath}/Cal.action?menthodName=divided";
	}
	calForm.submit();
}

</script>
</head>
<body>
<form name="calForm" method="post" action="">
num1:<input type="text" name="num1" ><br>
num2:<input type="text" name="num2" ><br>
<button οnclick="doSub(1)">+</button>
<button οnclick="doSub(2)">-</button>
<button οnclick="doSub(3)">*</button>
<button οnclick="doSub(4)">/</button>
</form>
</body>
</html>

  

 

结果如下

 

转载于:https://www.cnblogs.com/xmf3628/p/11079581.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义mvc 的相关文章

随机推荐

  • php 操作系统之间的一些黑魔法(绕过文件上传a.php/.)

    http wonderkun cc index html p 626 0x00 前言 做了一个CTF题目 遇到了一些有趣的东西 所以写了这篇文章记录了一下 但是我却不明白造成这个问题的原因在哪里 所以不知道给文章起什么标题 就姑且叫这个非常
  • 汇总

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 汇总图像语义分割那些质量最好的数据集与常用benchmark数据集 前言 图像语义分割是计算机视觉最经典的任务之一 早期的图像分割主要有以下几种实现方法 基于像素分布的分
  • 4.3、Flink任务怎样读取Kafka中的数据

    目录 1 添加pom依赖 2 API使用说明 3 这是一个完整的入门案例 4 Kafka消息应该如何解析 4 1 只获取Kafka消息的value部分 4 2 获取完整Kafka消息 key value Metadata 4 3 自定义Ka
  • 我读zookeeper源码系列1

    一 准备工作 1 zookeeper版本 01 zookeeper 3 4 x 企业最常用 大数据技术组件最常用 基本维持在 3 4 5 3 4 6 3 4 7 这几个版本 02 zookeeper 3 5 x 03 zookeeper 3
  • MYSQL的系统数据表空间,用户数据表空间,系统临时表空间,用户临时表空间详解

    系统数据表空间 系统表空间可以有一个或多个数据文件 默认情况下 会在数据目录中创建一个名为ibdata1的系统表空间数据文件 系统表空间数据文件的大小和数量由innodb data file path启动选项定义 mysql gt show
  • vue-element-admin教程

    vue element admin 是一个后台前端解决方案 它基于 vue 和 element ui实现 它使用了最新的前端技术栈 内置了 i18 国际化解决方案 动态路由 权限验证 提炼了典型的业务模型 提供了丰富的功能组件 它可以帮助你
  • 个人信贷违约预测代码实战

    本次分享一个数据挖掘实战项目 个人信贷违约预测 项目背景 当今社会 个人信贷业务发展迅速 但同时也会暴露较高的信用风险 信息不对称在金融贷款领域突出 在过去时期借款一方对自身的财务状况 还款能力及还款意愿有着较为全面的掌握 而金融机构不能全
  • c/c++,char型数组转化为int类型

    char型数组转int类型 这几天遇到需要将int等类型转换并保存在char数组中 同时还需要将char数组转换为int等类型进行显示 1 int等类型转换并保存在char数组中 int为4字节 char为1字节 由长变短 容易发出截断 数
  • 如何在 Flask 项目中使用 MQTT

    Flask 是一个使用 Python 编写的轻量级 Web 应用框架 其被称为 微框架 因为它使用简单的核心 用扩展增加其他功能 例如 ORM 窗体验证工具 文件上传 各种开放式身份验证技术等 MQTT 是一种基于发布 订阅模式的 轻量级物
  • linux窗口不能切换,linux一些技巧, 窗口切换 进入文字模式,设置错误无法启动等...

    一 如何进入文字模式 当安装Linux时 可选择自动后要进入文字模式或时图形模式 如果选择的时文字模式则可略过此说明 若是直接进入X Window的图形模式 仍可以使用下列方式 进入文字模式 1 在X Window中打开文字模式窗口 在默认
  • 【详解Vue中请求拦截器】

    文章目录 前言 一 安装依赖 二 定义拦截器 1 创建一个interceptors js文件用于定义拦截器 2 注册插件 3 发送请 总结 前言 提示 Vue请求拦截器通常用于在发送请求之前对请求进行一些处理 例如添加请求头 验证用户身份
  • Springboot + MySQL+ JPA Ⅶ querydsl使用方法

    一 pom xml 1 添加依赖 版本号4 1会导致报错 使用4 4 0之后解决
  • 1.GraphPad Prism 8软件安装

    1 解压文件 2 执行 exe文件 这里需要记住安装路径 D Program Files GraphPad Prism 8 我安装在这个路径下 一直下一步完成安装 3 破解软件 成功安裝後 將Crack中的1個文件複製到軟件安裝目錄下替換即
  • 若依登录界面美化

    效果图如下 代码如下
  • PanDownload——卢本伟修订版,复活了!60MB/s!附下载地址

    最近几天 听说PanDownload 复活了 有人接盘了 重新制作上线 推出了更加强劲的复活版 但是笔者去下载了一下 发现并不能使用 于是经过百般搜寻 发现被人提供的已经是旧版了 于是 我找到了最新版 9月20日更新的最新版 放张图 大家先
  • 解决jupyter lab需要输入密码但是密码无效的问题

    近期通过ssh链接远程服务器 打开jupyter lab时需要输入密码 先运行了以下指令 cd jupyter ls vi XXX 配置文件 复制配置文件中c ServerApp password到网页的pwd中 连token都没有 只有p
  • 闲鱼副业卖什么比较好?闲鱼无货源卖什么产品好?

    闲鱼卖货 无成本投入 只需要自己选款 然后自己加价后再闲鱼上架 买家购买后你再从上家进行购买 后面就是卖一件赚一件 缺点就是闲鱼只能一次上架50个货物 这个只要肯花时间 不敢保证你月入过万 但随便玩玩2000还是很稳定的 那么闲鱼卖什么比较
  • Linux软件系统受欢迎 在新加坡取得增长势头

    2005 09 01 来自 联合早报 王阳发 Linux软件系统不只进驻了办公室后端的服务器 也进入了国防部和国家图书馆的桌面 Linux等开放源代码软件 在本地市场取得增长 但也引起知识产权论争 Linux等开放源代码 Open Sour
  • 给指定服务器加路由,无线路由器如何给终端分配指定的IP地址?

    在特定的一些应用 带宽控制 虚拟服务器 上网控制 中 需要为受控终端设置固定的IP地址 通过IP地址来控制该终端 但对于部分移动终端 如手机 IPAD等设备 手动指定IP地址操作复杂 而且会导致移动到新的网络后的连通性问题 路由器的静态地址
  • 自定义mvc

    1 什么是MVC MVC全名是Model View Controller 是模型 model 视图 view 控制器 controller 的缩写 它是一种软件设计典范 用一种业务逻辑 数据 界面显示分离的方法组织代码 2 MVC结构 V