MVC框架已经使用的非常广泛了,现在我也自制一个MVC框架来加深我对MVC框架的理解。
首先MVC共分三个内容,M(Model) V(View) C(Controller)。
M:主要就是一些Action,用来处理业务内容和数据库的操作。
V:视图,用于向用户显示内容。
C:所有的请求由这里来管理,进行分配。分发业务请求。
1.在web.xml文件中加入一个servlet,去拦截所有的满足条件请求,这些请求由控制键(C)来进行分发管理。
其中具有自制mvc框架的配置文件:mvc-config.xml,当做参数设置在servlet中。
2.controller文件:
Controller中使用了ConfigHelper类来加载缓存。
3.ConfigHelper文件:
用来加载配置文件。
4.ActionFactory:
ActionFactory的工厂类。用来创建Controller。
5.ActionPackage:
Controller相关信息的包装类。
运行起来之后在浏览器上输入:http://localhost:8080/mvc/main.do?function=hello
然后会在控制台输出一句话:"this is hello!!!",这里没有连接到页面,你们可以去扩展此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: 176291935@qq.com
* </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: 176291935@qq.com
* </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: 176291935@qq.com
* </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: 176291935@qq.com
* </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: 176291935@qq.com
* </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框架