对于一个MVC框架来说,最重要的就是C了,特别是前端控制器。前端控制器首先要根据URL请求,来分发该请求应该由哪个controller中哪个方法来处理;然后controller处理完后,还要根据其返回值,最终定位要应该返回哪张视图给客户端,如图:
为些我们实现一个MVC框架主要就是实现这个前端控制器。我写了一个很简单的MVC框架,我将代码分享给大家。
由于工程是由maven搭建的,则pom.xml如下:
(其中jetty也配置好)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cloud.mvc</groupId> <artifactId>mvc-framework</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>mvc-framework Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> </dependencies> <build> <finalName>mvc-framework</finalName> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.10</version> <configuration> <contextPath>/test</contextPath> <connectors> <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> <port>8080</port> </connector> </connectors> <scanIntervalSeconds>3</scanIntervalSeconds> </configuration> </plugin> </plugins> </build> </project>
如果要使用我这个框架,则工程目录下必需要有一个mvc.xml文件,而且文件名必需是mvc.xml。该文件的作用和struts2框架中的struts.xml的作用类似。
<?xml version="1.0" encoding="UTF-8"?> <mvc> <action name="user/select" class="com.cloud.mvc.controller.UserController" method="select"> <result name="success">/WEB-INF/view/index.jsp</result> <result name="faild">/index.jsp</result> </action> </mvc>
两个用于封装配置信息的类。
ActionConfig.java
package com.cloud.mvc.config; import java.util.HashMap; import java.util.Map; public class ActionConfig { private String name; private String clazz; private String method; private Map<String, ResultConfig> result; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public Map<String, ResultConfig> getResult() { return result; } public void setResult(Map<String, ResultConfig> result) { this.result = result; } public ActionConfig() { } public ActionConfig(String name, String clazz, String method) { this.name = name; this.clazz = clazz; this.method = method; this.result = new HashMap<String, ResultConfig>(); } }
ResultConfig.java
package com.cloud.mvc.config; public class ResultConfig { private String name; private String content; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public ResultConfig() { } public ResultConfig(String name, String content) { this.name = name; this.content = content; } }
用到的工具类。
XMLUtil.java
package com.cloud.mvc.util; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.cloud.mvc.config.ActionConfig; import com.cloud.mvc.config.ResultConfig; public class XMLUtil { public static Map<String, ActionConfig> parseConfig() throws Exception { Map<String, ActionConfig> actionConfigs = new HashMap<String, ActionConfig>(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputStream in = XMLUtil.class.getClassLoader().getResourceAsStream("mvc.xml"); Document document = db.parse(in); Element root = document.getDocumentElement(); NodeList actionNodes = root.getChildNodes(); for (int i = 0; i < actionNodes.getLength(); i++) { Node action = actionNodes.item(i); if (null != action && action.getNodeType() == Node.ELEMENT_NODE) { NamedNodeMap nodeMaps = action.getAttributes(); String actionName = nodeMaps.getNamedItem("name").getNodeValue(); String actionClass = nodeMaps.getNamedItem("class").getNodeValue(); String actionMethod = nodeMaps.getNamedItem("method").getNodeValue(); ActionConfig actionConfig = new ActionConfig(actionName, actionClass, actionMethod); NodeList resultNodes = action.getChildNodes(); for (int j = 0; j < resultNodes.getLength(); j++) { Node result = resultNodes.item(j); if (null != result && result.getNodeType() == Node.ELEMENT_NODE) { String resultName = result.getAttributes().getNamedItem("name").getNodeValue(); String resultContent = result.getTextContent(); ResultConfig resultConfig = new ResultConfig(resultName, resultContent); Map<String, ResultConfig> resultConfigs = actionConfig.getResult(); resultConfigs.put(resultName, resultConfig); } } actionConfigs.put(actionName, actionConfig); } } return actionConfigs; } }
最为核心的前端控制器。
DispatcherServlet.java
package com.cloud.mvc.servlet; import java.io.IOException; import java.lang.reflect.Method; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.cloud.mvc.config.ActionConfig; import com.cloud.mvc.config.ResultConfig; import com.cloud.mvc.util.XMLUtil; public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = -1105148104350928967L; private Map<String, ActionConfig> actionConfigs; @Override public void init() throws ServletException { super.init(); try { actionConfigs = XMLUtil.parseConfig(); } catch (Exception e) { 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 contextPath = req.getContextPath(); String uri = req.getRequestURI(); String actionName = uri.substring(contextPath.length() + 1, uri.length()); ActionConfig actionConfig = actionConfigs.get(actionName); String clazz = actionConfig.getClazz(); String method = actionConfig.getMethod(); String result = null; try { Class<?> clazzObject = Class.forName(clazz); Method controllerMethod = clazzObject.getMethod(method, HttpServletRequest.class); result = (String) controllerMethod.invoke(clazzObject.newInstance(), req); } catch (Exception e) { e.printStackTrace(); } Map<String, ResultConfig> resultConfigs = actionConfig.getResult(); String returnPath = resultConfigs.get(result).getContent(); req.getRequestDispatcher(returnPath).forward(req,resp); } }
接下来就是将DispatcherServlet类配置到web.xml中。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>mvc</servlet-name> <servlet-class>com.cloud.mvc.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
在此只写一个controller类,用于测试。
UserController.java
package com.cloud.mvc.controller; import javax.servlet.http.HttpServletRequest; public class UserController { public String select(HttpServletRequest req) { return "faild"; } }
运行结果:
相关推荐
PHP MVC 说明文档
微信开发php+mvc框架
自己动手做框架——ORM,MVC,IOC框架及整合视频教程 源码
自己动手写SpringMVC框架项目源代码,更多详情请查看相关博客:https://blog.csdn.net/qq_31142553/article/details/86582066
java自动动手做框架mvc
本书旨在通过一些案例教授读者怎样自己来开发Struts框架
一、文件结构 建立3个文件夹 controller文件夹存放控制器文件 view文件夹存放视图文件 model文件夹存放数据文件 建立1个index.php 作为唯一入口 二、控制器 我们在controller文件夹下建立一个democontroller.php文件...
Spring MVC 框架在 Java 的 Web 项目中应该是无人不知的吧,你不会搭建一个 Spring 框架?作为身为一个刚刚学习Java的我都会,如果你不会的话,那可真令人忧伤。 1.在 MyEclipse 创建项目后,可以以选择的方式去...
看了一段时间的MVC和easyUI,决定自己动手试试做一个项目,框架搭好了,测试没问题,里面有登录的代码,还有一个绑定datatagrid的代码,下载 改下数据库连接就可以了,刚学MVC代码写的有点差
2 MVC框架——模仿struts2 3 IOC框架——模仿Spring 4 框架整合及项目实例 使用技术: 开发语言:Java 开发工具:Eclipse,MyEclipse 数据库:MySQL 数据库工具:Navicat 建模工具:Rose,PowerDesigner 预期目标...
spring mvc,spring,mybatis框架的整合,适合初学者
然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...
然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...
mvc快速入门!动手为主从实践中学习!doc格式
然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean容器、IoC框架、MVC框架,所涉及的代码也是整个框架的核心基础。为了使框架具备AOP特性,从代理技术讲到 AOP ...
作为一个PHPer要提高自己的对PHP和MVC的框架的认识,所以自己写一个MVC框架是很有必要的, 即使不是很完善,但是自己动手写一个轻量简洁的PHP MVC框架起码对MVC的思想有一定的了解,而且经过自己后期的完善会渐渐...
然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...
然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...
完善相关细节,并对已有代码进行优化:然后基于传统Servlet框架搭建一款轻量级Java Web框架,一-切都是从零开始,逐个实现类加载器、Bean容器、loC框架、MVC框架,所涉及的代码也是整个框架的核心基础。为了使框架...