`
芝加哥09
  • 浏览: 59359 次
社区版块
存档分类
最新评论

自己动手写MVC框架

mvc 
阅读更多

对于一个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";
    }

}

 运行结果:



 

  • 大小: 7.2 KB
  • 大小: 9.8 KB
0
1
分享到:
评论

相关推荐

    自己动手写PHP MVC 框架.

    PHP MVC 说明文档

    微信开发php+mvc框架

    微信开发php+mvc框架

    自己动手做框架——ORM,MVC,IOC框架

    自己动手做框架——ORM,MVC,IOC框架及整合视频教程 源码

    自己动手写SpringMVC框架项目源代码

    自己动手写SpringMVC框架项目源代码,更多详情请查看相关博客:https://blog.csdn.net/qq_31142553/article/details/86582066

    java自动动手做框架mvc

    java自动动手做框架mvc

    自己动手写Struts:构建基于MVC的Web开发框架

    本书旨在通过一些案例教授读者怎样自己来开发Struts框架

    php打造属于自己的MVC框架

    一、文件结构 建立3个文件夹 controller文件夹存放控制器文件 view文件夹存放视图文件 model文件夹存放数据文件 建立1个index.php 作为唯一入口 二、控制器 我们在controller文件夹下建立一个democontroller.php文件...

    Spring MVC 框架搭建

    Spring MVC 框架在 Java 的 Web 项目中应该是无人不知的吧,你不会搭建一个 Spring 框架?作为身为一个刚刚学习Java的我都会,如果你不会的话,那可真令人忧伤。 1.在 MyEclipse 创建项目后,可以以选择的方式去...

    C# MVC4+EasyUI框架搭建

    看了一段时间的MVC和easyUI,决定自己动手试试做一个项目,框架搭好了,测试没问题,里面有登录的代码,还有一个绑定datatagrid的代码,下载 改下数据库连接就可以了,刚学MVC代码写的有点差

    自己动手写框架(含PPT、UML、文档、依赖包、代码)

    2 MVC框架——模仿struts2 3 IOC框架——模仿Spring 4 框架整合及项目实例 使用技术: 开发语言:Java 开发工具:Eclipse,MyEclipse 数据库:MySQL 数据库工具:Navicat 建模工具:Rose,PowerDesigner 预期目标...

    自己动手搭建SSM框架

    spring mvc,spring,mybatis框架的整合,适合初学者

    架构探险 从零开始写javaweb框架

    然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...

    架构探险 从零开始写javaweb框架 高清pdf 书签版

    然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...

    asp.net中mvc框架的一个demo

    mvc快速入门!动手为主从实践中学习!doc格式

    架构探险——从零开始写Java Web框架 绝对完整!强烈推荐

    然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean容器、IoC框架、MVC框架,所涉及的代码也是整个框架的核心基础。为了使框架具备AOP特性,从代理技术讲到 AOP ...

    PHP框架CXPHP.zip

    作为一个PHPer要提高自己的对PHP和MVC的框架的认识,所以自己写一个MVC框架是很有必要的, 即使不是很完善,但是自己动手写一个轻量简洁的PHP MVC框架起码对MVC的思想有一定的了解,而且经过自己后期的完善会渐渐...

    架构探险 从零开始写javaweb框架.pdf

    然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...

    架构探险-----从零开始写javaweb框架.pdf

    然后基于传统 Servlet 框架搭建一款轻量级 Java Web 框架,一切都是从零开始,逐个实现类加载器、Bean 容器、IoC 框架、MVC 框架,所涉及的代码也是整个框架的核心基础。为了使框架具备 AOP 特性,从代理技术讲到 ...

    架构探险 从零开始写Java Web框架.pdf

    完善相关细节,并对已有代码进行优化:然后基于传统Servlet框架搭建一款轻量级Java Web框架,一-切都是从零开始,逐个实现类加载器、Bean容器、loC框架、MVC框架,所涉及的代码也是整个框架的核心基础。为了使框架...

Global site tag (gtag.js) - Google Analytics