`
sunqitang
  • 浏览: 78538 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自制MVC框架:TonyMVC

    博客分类:
  • SSH
阅读更多

MVC框架已经使用的非常广泛了,现在我也自制一个MVC框架来加深我对MVC框架的理解。

 

首先MVC共分三个内容,M(MODEL)V(VIEW)C(controller)。

M:主要就是一些Action,用来处理业务内容和数据库的操作。

V:视图,用于向用户显示内容。

C:所有的请求由这里来管理,进行分配。分发业务请求。

 

 

 

1 在web.xml文件中加入一个servlet,去拦截所有的满足条件请求,这些请求由控制键(C)来进行分发管理。

 <servlet>
    <description>DispatchServlet</description>
    <display-name>DispatchServlet</display-name>
    <servlet-name>DispatchServlet</servlet-name>
    <servlet-class>com.hrbust.mvc.controller.DispatchServlet</servlet-class>
    <init-param>
      <description>Configuration File</description>
      <param-name>configFile</param-name>
      <param-value>WEB-INF/mvc-config.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatchServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

 其中具有自制MVC框架的配置文件:mvc-config.xml,当做参数设置在servlet中。

 

2 controller文件:

 

  初始化:读取配置文件,把相应的Action信息加入到ActionMap中。

      并获取ActionMap。此时ActionMap为缓存。

  doGet方法: 取得请求URL,把它进行拆分。

 

  Controller中使用了ConfigHelper类来加载缓存。

 

package com.hrbust.mvc.controller;

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

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hrbust.mvc.action.ActionPackager;
import com.hrbust.mvc.config.ConfigHelper;
import com.hrbust.mvc.util.RegexUtil;

/**
 * Action分发类<br>
 * 将请求分派给指定Action处理
 * 
 * @author Welkin
 *
 */
public class DispatchServlet extends HttpServlet {

	private static final long serialVersionUID = 1131523345611250389L;

	private static final String CONTENT_TYPE="text/html;charset=UTF-8";
	
	private Map<String,ActionPackager> actionsMap;
	
	/*public static String DataURL=null;
	public static String MarkURL=null;
	public static String PastePicsURL=null;*/
	
	/**
	 * Constructor of the object.
	 */
	public DispatchServlet() {
		super();
	}
	
	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		//read config values from the web.xml
		
		// 通过ServletContext取得工程的绝对物理路径
        ServletContext sct = getServletContext();
        String realPath = sct.getRealPath("/");
		
        // 通过ServletConfig实例取得初始化参数configFile
        ServletConfig config=this.getServletConfig();        
        String CfgFile=config.getInitParameter("configFile");

        // 组合配置文件全物理路径
        CfgFile=realPath+CfgFile;
        
        //创建ConfigHelper对象,初始化actionsMap
        ConfigHelper configHelper=new ConfigHelper(CfgFile,config);
        actionsMap=configHelper.getActionsMap();
		
	}
	
	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		actionsMap=null;
	}

	/**
	 * The doGet method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType(CONTENT_TYPE);
		
		// 取得请求的URL
        String reqURL=request.getServletPath();
        
        // 取得模式匹配字符串,取得请求后缀
        String patternStr;
        if(reqURL.contains("?")){
            patternStr=RegexUtil.getMatchedString("([.])(.*)?",reqURL);
        }
        else{
            patternStr=RegexUtil.getMatchedString("([.])(.*)$",reqURL);
        }
        
        // 取得请求的Action名称
        String actionName=RegexUtil.getMatchedString("/(.*)[.]"+patternStr,reqURL);
        
        ActionPackager actionPackager=actionsMap.get(actionName);
        
        //如果请求的Action为空,则返回404错误
        if(actionPackager==null)
        	response.sendError(HttpServletResponse.SC_NOT_FOUND);
        else{
        	String methodName=request.getParameter(actionPackager.getMethodName());

            //执行Action中的方法
            Class<?> actionClass=actionPackager.getActionClass();
    		Object actionObj=actionPackager.getActionObj();
    		
    		try {
				Method method = actionClass.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
				method.invoke(actionObj, request,response);
			} catch (NoSuchMethodException e) {
				//如果请求方法不存在,抛出404错误
				response.sendError(HttpServletResponse.SC_NOT_FOUND);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
        
	}

	/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		this.doGet(request, response);
	}

}

 

 

3 ConfigHelper文件:

 

  用来加载配置文件。

  创建Action的包装类ActionPackager和Action的工厂类ActionFactory。

 

package com.hrbust.mvc.config;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletConfig;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.hrbust.mvc.ActionFactory;
import com.hrbust.mvc.action.Action;
import com.hrbust.mvc.action.ActionPackager;

/**
 * 配置文件Helper类<br>
 * 用于获取配置文件相关
 * 
 * @author Welkin
 *
 */
public class ConfigHelper {
	
	public static Log log=LogFactory.getLog(ConfigHelper.class);
	
	private ActionFactory actionFactory;
	
	private Document document;
	
	
	/**
	 * 构造函数,加载配置文件,初始化document
	 * @param configFile
	 */
	public ConfigHelper(String configFile,ServletConfig servletConfig){

		log.info("加载mvc配置文件...");
		
		try {
			File file = new File(configFile);
			SAXReader reader = new SAXReader();
			document = reader.read(file);
		} catch (DocumentException e) {
			log.error("配置文件不存在或格式不正确");
			e.printStackTrace();
		}
		
		log.info("初始化ActionFactory...");
		if(servletConfig==null){
			try {
				throw new Exception();
			} catch (Exception e) {
				log.error("ServletConfig参数为Null,ActionFactory初始化失败");
				e.printStackTrace();
			}
		}else{
			actionFactory=new ActionFactory(servletConfig);
		}
	}
	
	public Map<String,ActionPackager> getActionsMap(){
		
		log.info("读取mvc配置文件,装载至缓存中...");
		
		Map<String,ActionPackager> actionsMap=new HashMap<String,ActionPackager>();
		
		Element root = document.getRootElement();
		List<?> actionElms=root.elements("action");
		
		//遍历所有action元素
		for(int i=0;i<actionElms.size();i++){
			Element actionElm  = (Element)actionElms.get(i);
			ActionPackager action=new ActionPackager();
			
			String actionClassPath=actionElm.attributeValue("class");
			Action actionObj=actionFactory.getActionInstance(actionClassPath);
			

			action.setName(actionElm.attributeValue("name"));
			action.setClassPath(actionClassPath);
			action.setMethodName(actionElm.attributeValue("method"));
			
			action.setActionClass(actionObj.getClass());
			action.setActionObj(actionObj);
			
			actionsMap.put(action.getName(), action);
		}
		
		log.info("装载完成");
		
		return actionsMap;
	}
	
	
}

 

 

4 ActionFactory

 

  ActionFactory的工厂类。用来创建Action。

package com.hrbust.mvc.action;

import javax.servlet.ServletConfig;

/**
 * SuperAction<br>
 * 所有Action的父类
 * 
 * @author Welkin
 */
public abstract class Action{
	
	private static ServletConfig config;
	
	/**
	 * 注入servletConfig
	 * 
	 * @param servletConfig
	 */
	public static void setServletConfig(ServletConfig servletConfig){
		config=servletConfig;
	}
	
	/**
	 * 得到ServletConfig
	 * 
	 * @return
	 */
	protected ServletConfig getServletConfig(){
		return config;
	}
}

 

 

5 ActionPackager

 Action相关信息的包装类。

 

package com.hrbust.mvc;

import javax.servlet.ServletConfig;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hrbust.mvc.action.Action;

/**
 * Action 工厂
 * 
 * @author Welkin
 *
 */
public class ActionFactory {
	
	public static Log log=LogFactory.getLog(ActionFactory.class);
	private ServletConfig servletConfig;
	
	public ActionFactory(ServletConfig servletConfig){
		this.servletConfig=servletConfig;
	}
	
	/**
	 * 得到Action实例
	 * @return
	 */
	public Action getActionInstance(String actionClassPath){
		
		Class<?> actionClass=null;
		Action actionObj=null;
		
		try {
			
			//向Action中注入servletConfig
			Action.setServletConfig(servletConfig);
			
			//实例化Action子类
			actionClass=Class.forName(actionClassPath);
			actionObj= (Action)actionClass.newInstance();
			log.debug("创建"+actionClassPath+"实例");
			
		}catch (ClassNotFoundException e) {
			log.error("Action相关类没有找到");
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}
		return actionObj;
	}
	
}

 

 

分享到:
评论
1 楼 hardPass 2010-05-06  
能看看你的mvc-config.xml 啊?

相关推荐

    Yifengsyj_V2.4_XiTongZhiJia.rar

    Yifengsyj_V2.4_XiTongZhiJia

    joblib-0.14.1-py2.py3-none-any.whl

    该资源为joblib-0.14.1-py2.py3-none-any.whl,欢迎下载使用哦!

    机械臂机械臂机械臂机械臂机械臂机械臂测试

    机械臂机械臂机械臂机械臂机械臂机械臂测试

    3dmax插件CGOMax塌陷工具.ms

    3dmax插件

    FIndSecBugs、Findbugs、infer、PMD 4个免费的SAST工具中的Java Checker

    FIndSecBugs、Findbugs、infer、PMD 4个免费的SAST工具中的Java Checker

    基于STM32的寻迹壁障自平衡小车:蓝牙控制与PID算法实现

    内容概要:本文详细介绍了基于STM32F103C6T6的自平衡小车的设计与实现。核心组件包括MPU6050陀螺仪用于姿态检测,通过I2C通信进行初始化配置;采用经典的PID算法实现平衡控制,重点讨论了PID参数的整定方法及其对车辆稳定性的影响;蓝牙模块HLK-B40实现了手机APP远程控制功能,提供了详细的指令解析和异常处理策略;电机驱动选用DRV8833,强调了PWM频率设置和死区时间配置的重要性。此外,文中还涉及了超声波避障、红外寻迹等功能模块的扩展思路以及一些实用技巧,如电池选择、电源管理和LED灯光效应用。 适合人群:具有一定嵌入式系统开发经验的技术爱好者、高校学生或相关领域的工程师。 使用场景及目标:适用于希望深入了解自平衡小车工作原理和技术细节的人群。主要目标是帮助读者掌握从硬件搭建到软件编程的全流程,能够独立完成类似项目的开发。 其他说明:文中不仅提供了完整的代码片段,还分享了许多实践经验,包括常见错误及解决方案,有助于初学者少走弯路。

    大彩串口屏开发-设置密码

    适用于刚开始开发大彩串口屏的开发者,功能包括输入密码进入主页面和修改密码

    基于Matlab与Yalmip的多用户储能电站日前经济调度优化模型

    内容概要:本文详细介绍了利用Matlab及其Yalmip工具箱,结合Gurobi求解器,实现多用户(如工业园区内的多个工厂)储能电站的日前经济调度优化。主要内容涵盖模型建立、变量定义、目标函数设定、约束条件配置以及求解过程。文中通过具体的代码实例展示了如何根据分时电价和各用户的用电需求,制定最优的储能充放电计划,从而达到降低总体电费的目的。此外,还讨论了一些常见的实现细节和技术难点,如充放电效率的正确处理、初始荷电状态(SOC)的设定等。 适合人群:具有一定编程基础并对电力系统优化感兴趣的工程师或研究人员。 使用场景及目标:适用于希望减少电费支出并提高能源利用效率的企业或机构。通过学习本文提供的方法,能够掌握如何构建和求解类似的优化问题,进而应用于实际工程项目中。 其他说明:文中提到的技术手段不仅限于储能调度,还可以扩展到其他类型的资源分配问题。对于想要深入了解优化理论及其工程应用的人来说,这是一个很好的入门案例。

    西门子S7-1200 PLC五轴伺服控制:基于工艺对象与脉冲输出的第三方伺服集成方案

    内容概要:本文详细介绍了如何利用西门子S7-1200 PLC及其内置的工艺对象特性,实现对五个第三方伺服驱动器的精确控制。主要内容涵盖硬件配置、软件编程、参数设置以及常见问题解决方案。文中提供了具体的代码示例和技术细节,帮助读者理解和实施这一复杂的控制系统。此外,还分享了一些实际应用中的经验和教训,确保系统的稳定性和可靠性。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些熟悉西门子PLC编程并且希望深入了解多轴伺服控制的人群。 使用场景及目标:本指南旨在指导用户完成从硬件搭建到软件编程的全过程,最终达到高效稳定的五轴伺服控制效果。具体应用场景包括但不限于包装生产线、贴标机以及其他需要精密运动控制的机械设备。 其他说明:作者强调了多个需要注意的关键点,如脉冲信号线的选择、伺服报警信号的处理、电子齿轮比的计算等。同时提醒读者关注某些特定型号PLC的功能限制,并给出了优化建议。

    工业自动化中欧姆龙CP1E与三菱变频器Modbus RTU通讯实现及应用

    内容概要:本文详细介绍了欧姆龙CP1E PLC与三菱FR-E700变频器通过Modbus RTU进行通信的方法。首先,文中列举了所需的硬件设备及其连接方法,强调了正确的接线方式和必要的硬件配置。接着,深入讲解了PLC程序的具体编写步骤,包括通讯参数初始化、正反转控制、频率设定等功能的实现。此外,还涉及了触摸屏的关键配置以及一些常见的调试技巧和注意事项。最后,作者分享了一些实际应用中的经验教训,如通讯超时重试机制、数据格式转换等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些需要进行PLC与变频器通信项目的人员。 使用场景及目标:适用于需要实现PLC与变频器之间的稳定通信的工程项目,帮助技术人员快速掌握相关技术和解决实际问题。 其他说明:文中提供了大量实用的技术细节和实践经验,对于初学者来说是非常宝贵的学习资料。同时,也提到了一些容易忽视的小细节,有助于提高系统的可靠性和稳定性。

    基于非对称纳什谈判的多微网电能共享优化策略及其MATLAB实现

    内容概要:本文详细介绍了利用非对称纳什谈判模型进行多微网电能共享优化的MATLAB代码实现。首先,通过合作博弈将多个微网的总效益最大化,然后通过议价分配子问题确保各微网按贡献公平分配收益。文中展示了如何使用ADMM算法进行分布式求解,同时考虑了电转气设备和碳捕集系统的低碳调度。实验结果显示,联合调度相比独立运行降低了14.7%的成本和22.3%的碳排放。此外,代码设计中特别强调了隐私保护,使得各微网可以在不泄露敏感数据的情况下进行协作。 适合人群:从事微电网调度优化研究的技术人员、研究生以及相关领域的研究人员。 使用场景及目标:适用于希望深入了解微电网电能共享优化策略的研究人员和技术开发者,旨在提供一种高效、公平且环保的多微网协作方法。 其他说明:代码中包含了详细的注释和数学推导,便于理解和修改。建议在配置CPLEX和MOSEK求解器环境下运行代码,以获得最佳性能。

    智能穿搭_ComfyUI_模型换装_SegVITON_实时服_1744169167.zip

    智能穿搭_ComfyUI_模型换装_SegVITON_实时服_1744169167.zip

    MATLAB/Simulink中电动助力转向系统(EPS)建模及控制策略实现

    内容概要:本文详细介绍了如何利用MATLAB/Simulink进行电动助力转向系统(EPS)的建模及其控制策略的实现。首先,文章阐述了EPS系统的基本组成,包括方向盘模块、扭矩传感器、助力电机以及齿轮齿条机构,并针对各个部分进行了具体的数学建模。接着,重点讨论了PID控制算法的应用,包括参数整定的方法和注意事项,确保系统的稳定性和平顺性。此外,文中还涉及到了一些常见的仿真问题及其解决方案,如代数环问题、信号噪声处理等。最后,通过对仿真结果的分析,展示了所建立模型的有效性和优越性能。 适合人群:具有一定MATLAB/Simulink基础并希望深入了解汽车电子控制系统特别是EPS系统的工程师和技术爱好者。 使用场景及目标:适用于从事汽车工程领域的研究人员和技术人员,旨在帮助他们掌握EPS系统的建模方法和控制策略,提高仿真的准确性,从而更好地应用于实际产品开发中。 其他说明:文章不仅提供了详细的理论推导和代码示例,还分享了许多实践经验,有助于读者更快地理解和应用相关知识。

    特种电机Maxwell与Simplorer联合仿真的关键技术及应用

    内容概要:本文详细介绍了特种电机(如轴向磁通电机和军用级永磁同步电机)在Maxwell和Simplorer联合仿真中的应用和技术细节。首先,文章讲解了Maxwell中三维模型的参数化设置,特别是极弧系数的自动化调整和绕组编号规则。其次,探讨了Simplorer中电路模型的构建,尤其是IGBT死区时间和PWM模块的配置。接着,强调了两者之间的耦合接口配置,包括数据传输步长和插值方式的选择。此外,文章还讨论了仿真波形的分析方法,如效率MAP图和启动瞬间电流的解读。最后,分享了一些实践经验,如将控制算法生成C代码烧入DSP进行交叉验证,以及仿真步长的分段设置。 适合人群:从事电机设计和仿真的工程师,特别是对特种电机感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要进行电磁场和控制系统联合仿真的场合,旨在提高仿真精度和效率,缩短产品研发周期。通过掌握文中提到的技术细节,可以更好地理解和解决仿真过程中常见的问题。 其他说明:文章提供了大量具体的代码示例和参数设置建议,帮助读者在实践中避免常见错误。同时,强调了仿真过程中需要注意的细节,如能量守恒检查和数据交互同步等问题。

    托盘输送机PLC程序双版本剖析:传统状态字与面向对象设计的较量

    内容概要:本文详细对比了两种不同风格的托盘输送机PLC程序,分别来自北起院的传统状态字版本(V1)和外企的面向对象版本(V2),均基于相同的硬件配置(S7-1500 PLC + KTP700 HMI)。V1版本使用大量状态字进行逻辑控制,代码复杂度较高,维护困难;而V2版本采用面向对象设计,利用功能块(FB)封装硬件抽象,极大提升了代码的可读性和维护性。文中还探讨了两者在与上位WCS系统的通信方式、报警处理、HMI界面生成等方面的异同,并分享了一些实际调试中的经验教训。 适合人群:从事工业自动化控制、PLC编程的技术人员,尤其是对托盘输送机系统感兴趣的工程师。 使用场景及目标:①理解传统状态字编程与现代面向对象编程在PLC程序中的优缺点;②掌握如何优化PLC程序结构,提高代码可维护性和开发效率;③学习如何正确配置PLC与上位系统的通信。 其他说明:文章不仅展示了两种编程方法的具体实现细节,还提供了实用的调试技巧和注意事项,有助于读者在实际工作中做出更好的技术决策。

    【嵌入式系统】第八届蓝桥杯嵌入式设计与开发省赛基础知识试题解析:选择题及答案分析

    内容概要:本文档为第八届蓝桥杯嵌入式设计与开发项目省赛的基础知识试题部分,主要考察参赛者对嵌入式系统的基本概念、逻辑运算、微控制器特性、通信接口及时钟源的选择等知识点的理解。试题涵盖逻辑表达式的化简、门电路的功能识别、STM32F103RBT6微控制器的内核及数据类型支持情况、RS232接口用于双机通信所需的最少信号线数量、STM32程序下载调试的方式选择、可菊链连接的接口类型、USB外设开发的时钟源选择、DMA的工作机制以及简单电路的电压计算等多个方面,旨在全面检验选手的专业知识掌握程度。 适合人群:具有一定的电子技术与单片机开发基础,准备参加嵌入式设计与开发竞赛的学生或爱好者。 使用场景及目标:①帮助参赛者熟悉并巩固嵌入式系统相关理论知识;②作为赛前复习资料,提高解题速度和准确性;③通过练习加深对各种硬件特性和应用场景的理解。 其他说明:文档提供了详细的答案解析,有助于学习者更好地理解题目背后的原理,建议结合实际项目经验进行学习,同时注意不同版本器件之间的差异。

    网络安全_CKCsec安全研究院_Web安全_区块链安全_C_1744170559.zip

    网络安全_CKCsec安全研究院_Web安全_区块链安全_C_1744170559.zip

    Carsim与Simulink联合仿真:自动驾驶横向控制与轨迹跟随算法研究

    内容概要:本文深入探讨了Carsim与Simulink联合仿真在自动驾驶领域的应用,特别是针对车道保持(LKA)和其他控制场景的多种轨迹跟随算法。文中介绍了基于PID、单点预瞄、多点预瞄、模糊PID、滑模变结构控制、预瞄+滑模变结构+模糊控制+预瞄距离自适应、MPC等多种控制策略的具体实现方式及其优缺点。此外,还讨论了ACC(自适应巡航控制)、AEB(自动紧急制动)和差动驱动等其他联合仿真模型的应用。每个控制策略都有详细的代码示例和技术细节,帮助读者理解其实现机制。 适合人群:从事自动驾驶技术研发的工程师、研究人员,以及对车辆动力学仿真和控制算法感兴趣的高校师生。 使用场景及目标:①研究和验证自动驾驶中的横向控制算法;②评估不同控制策略在各种驾驶场景下的表现;③优化控制参数以提高轨迹跟随精度和稳定性;④通过仿真减少实车测试的风险和成本。 阅读建议:由于涉及大量控制理论和具体实现代码,建议读者具备一定的控制工程和MATLAB/Simulink基础。同时,对于复杂的控制策略,可以通过逐步实验和调试加深理解。

    3dmax插件023-一键编织.ms

    3dmax插件

Global site tag (gtag.js) - Google Analytics