自制MVC框架:IAIMVC

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.iaiai.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文件:
Controller中使用了ConfigHelper类来加载缓存。
package com.iaiai.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.iaiai.mvc.action.ActionPackager;
import com.iaiai.mvc.config.ConfigHelper;
import com.iaiai.mvc.util.RexUtil;

/**
 * 
 * <p>
 * Title: DispatchServlet.java
 * </p>
 * <p>
 * E-Mail: [email protected]
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-10-14
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
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 {
		doPost(request, response);
	}

	/**
	 * 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 {
		response.setContentType(CONTENT_TYPE);

		// 取得请求的URL
		String reqURL = request.getServletPath();

		// 取得模式匹配字符串,取得请求后缀
		String patternStr;
		if (reqURL.contains("?")) {
			patternStr = RexUtil.getMatchedString("([.])(.*)?", reqURL);
		} else {
			patternStr = RexUtil.getMatchedString("([.])(.*)$", reqURL);
		}

		// 取得请求的Action名称
		String actionName = RexUtil.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();
			}
		}
	}

}


3.ConfigHelper文件:
用来加载配置文件。
package com.iaiai.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.iaiai.mvc.action.Controller;
import com.iaiai.mvc.action.ActionFactory;
import com.iaiai.mvc.action.ActionPackager;

/**
 * 
 * <p>
 * Title: ConfigHelper.java
 * </p>
 * <p>
 * E-Mail: [email protected]
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-10-14
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
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");
			Controller 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的工厂类。用来创建Controller。
package com.iaiai.mvc.action;

import javax.servlet.ServletConfig;

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


/**
 * 
 * <p>
 * Title: ActionFactory.java
 * </p>
 * <p>
 * E-Mail: [email protected]
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-10-14
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
public class ActionFactory {

	public static Log log = LogFactory.getLog(ActionFactory.class);
	private ServletConfig servletConfig;

	public ActionFactory(ServletConfig servletConfig) {
		this.servletConfig = servletConfig;
	}

	/**
	 * 得到Action实例
	 * 
	 * @return
	 */
	public Controller getActionInstance(String actionClassPath) {

		Class<?> actionClass = null;
		Controller actionObj = null;

		try {

			// 向Action中注入servletConfig
			Controller.setServletConfig(servletConfig);

			// 实例化Action子类
			actionClass = Class.forName(actionClassPath);
			actionObj = (Controller) actionClass.newInstance();
			log.debug("创建" + actionClassPath + "实例");

		} catch (ClassNotFoundException e) {
			log.error("Action相关类没有找到");
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return actionObj;
	}

}


package com.iaiai.mvc.action;

import javax.servlet.ServletConfig;

/**
 * 
 * <p>
 * Title: Controller.java
 * </p>
 * <p>
 * E-Mail: [email protected]
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-10-14
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
public abstract class Controller {

	private static ServletConfig config;

	/**
	 * 注入servletConfig
	 * 
	 * @param servletConfig
	 */
	public static void setServletConfig(ServletConfig servletConfig) {
		config = servletConfig;
	}

	/**
	 * 得到ServletConfig
	 * 
	 * @return
	 */
	protected ServletConfig getServletConfig() {
		return config;
	}

}


5.ActionPackage:
Controller相关信息的包装类。
package com.iaiai.mvc.action;

/**
 * 
 * <p>
 * Title: ActionPackager.java
 * </p>
 * <p>
 * E-Mail: [email protected]
 * </p>
 * <p>
 * QQ: 176291935
 * </p>
 * <p>
 * Http: iaiai.iteye.com
 * </p>
 * <p>
 * Create time: 2011-10-14
 * </p>
 * 
 * @author 丸子
 * @version 0.0.1
 */
public class ActionPackager {
	private String name; // action名称
	private String classpath; // action的完整路径
	private String methodName;

	private Class<?> actionClass;
	private Controller actionObj;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getClasspath() {
		return classpath;
	}

	public void setClasspath(String classpath) {
		this.classpath = classpath;
	}

	public String getMethodName() {
		return methodName;
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public Class<?> getActionClass() {
		return actionClass;
	}

	public void setActionClass(Class<?> actionClass) {
		this.actionClass = actionClass;
	}

	public Controller getActionObj() {
		return actionObj;
	}

	public void setActionObj(Controller actionObj) {
		this.actionObj = actionObj;
	}

}


运行起来之后在浏览器上输入:http://localhost:8080/mvc/main.do?function=hello
然后会在控制台输出一句话:"this is hello!!!",这里没有连接到页面,你们可以去扩展此mvc框架

猜你喜欢

转载自iaiai.iteye.com/blog/1196222
今日推荐