我们在学习自定义MVC框架的时候常常会听到Model1 ,Model2和MVC。那么什么是Model1 什么是Model2什么又是MVC呢?

什么是Model1?

Model1就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起。

什么是Model2?

Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形成一个Servlet,Model2也是基于MVC开发

什么是MVC框架?

MVC是三个单词的缩写,这三个单词分别为:模型(Model)、视图(View)和控制(Controller)。一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

其实我们之前也使用过MVC的思想,我们在学习Model2也就是Servlet的时候,用的思想就是基于MVC开发思想

既然我们已经知道了MVC的作用,那么我们就可以开发自己的MVC框架了,就以我们之前学习的Struts2框架为例,定义一个自己的MVC框架

如何开发自己的MVC框架?

开发前的准备   jar包

一个就够了,该jar包的作用就是解析xml文件

第一步:准备配置文档

既然是框架,那肯定少不了的东西就是配置文件

我们配置一个xml文件,如下

<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义我们的DOC约束文件 -->
<!-- 定义根节点 (包含元素)-->
<!-- ELEMENT 表示元素 -->
<!-- ATTLIST 表示属性 -->
<!DOCTYPE myframework[ <!ELEMENT myframework (actions)>
<!ELEMENT actions (action*)>
<!ELEMENT action (result*)> <!ATTLIST action
name CDATA #REQUIRED
class CDATA #REQUIRED
>
<!ATTLIST result
name CDATA #IMPLIED
redirect (true|false) "false"
>
]
>
<myframework>
<actions>
<action name="loginAction" class="action.LoginAction">
<result name="success">success.jsp</result>
<result name="input">index.jsp</result>
</action>
</actions>
</myframework>

第二步:我们准备自己的Action接口,用于存放结果集和要执行的方法

package action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public interface Action { //定义字符串常量
public static final String SUCCESS="success";
public static final String NONE="none";
public static final String ERROR="error";
public static final String INPUT="input";
public static final String LOGIN="login"; //准备一个方法,用于获取数据
public String execute(HttpServletRequest request, HttpServletResponse sponse)throws Exception;
}

第三步:定义一个ActionMapping用来存放Action节点

package action;

import java.util.HashMap;
import java.util.Map; /*
* Action 的配置文件信息
* */
public class ActionMapping {
//访问的Action的名称
private String name;
//访问的Action的对应的Action的类全称
private String ClassName;
//result定义的结果集
private Map<String,String> resultMAp=new HashMap<String, String>(); //往集合里面添加配置文件中的数据信息
public void addResult(String resultName,String result){
resultMAp.put(resultName, result);
} //根据resultName获取对应的result页面
public String getResult(String resultName){
return resultMAp.get(resultName);
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return ClassName;
}
public void setClassName(String className) {
ClassName = className;
} }

第四步:定义ActionMappingManager,管理ActionMapping

package action;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /*
* ActionMapping 的管理类
* */
public class ActionMappingManager {
/**管理ActionMapping 一个ActionMapping表示一个Action
* 但是我们配置文件中可能出现多个Action节点,所以我们需要一个ActionMapping的管理类
* */
private static Map<String,ActionMapping> actionMappings=new HashMap<String,ActionMapping>(); public ActionMappingManager() { }
//带参构造
public ActionMappingManager(String[] configFileNames){
for (String filaName : configFileNames) {
//调用根据文件名读取配置文件的方法
init(filaName);
}
} //根据Action名称获取到某一个具体的Action
public ActionMapping getActionMapping(String actionName){
//根据ActionName获取到Action
ActionMapping actionMapping=actionMappings.get(actionName);
return actionMapping;
} public void init(String configFileName){
try {
//读取配置文件,肯定用到了输入流
InputStream is=this.getClass().getResourceAsStream("/"+configFileName);
//开始读取xml文件
Document doc=new SAXReader().read(is);
//获取根节点
Element root=doc.getRootElement();
//获取Actions节点
Element actions = (Element)root.elementIterator("actions").next();
//开始遍历Actions节点
for(Iterator<Element> action=actions.elementIterator("action");action.hasNext();){
//获取到Action节点,将其属性进行封装
Element actionElement=action.next();
//获取到name
String name=actionElement.attributeValue("name");
//获取到ClassName
String ClassName=actionElement.attributeValue("class");
//一个Action对应着一个ActionMapping,创建ActionMapping进行赋值
ActionMapping actionMapping =new ActionMapping();
actionMapping.setName(name);
actionMapping.setClassName(ClassName);
//遍历Action的子元素result
for(Iterator<Element> result=actionElement.elementIterator("result");result.hasNext();){
Element resultElement = result.next();
//获取result属性值
String resultName=resultElement.attributeValue("name");
String resultValue=resultElement.getText();
//将每个result封装到ActionMapping中去
actionMapping.addResult(resultName, resultValue);
}
//将ActionMapping放入ActionMappingManager中去
actionMappings.put(actionMapping.getName(), actionMapping);
} } catch (Exception e) {
e.printStackTrace();
}
} }

第五步:利用反射机制,找到具体类的实例

package action;
/*
* 利用反射机制,根据类的类类型获取到类的实例
* */
public class ActionManager {
public static Action creatAction(String className){
Class clazz=null; try {
//判断当前线程是否有该Action
clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(clazz==null){
try {
//根据类的全路径,手动创建一个类的类类型
clazz=Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Action action=null;
try {
//根据类的类类型创建出一个类的实例
action=(Action)clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return action;
}
}

第六步:写业务逻辑Action

package action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LoginAction implements Action { public String execute(HttpServletRequest request, HttpServletResponse sponse)
throws Exception {
//写具体的业务逻辑 return SUCCESS;
} }

第七步:准备Servlet

package servlet;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import action.Action;
import action.ActionManager;
import action.ActionMapping;
import action.ActionMappingManager; public class MVCServlet extends HttpServlet { /**
出品:巴黎的雨季
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} /**
出品:巴黎的雨季 */ ActionMappingManager actionMappingManager=null; public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//根据ActionName获取到ActionMapping
ActionMapping actionMapping = actionMappingManager.getActionMapping(getActionName(request));
//根据ActionMapping中的ClassName获取到具体的类的实例
Action action = ActionManager.creatAction(actionMapping.getClassName());
//执行业务逻辑,获取到resultName
String resultName = action.execute(request, response);
//根据resultName获取具体的result视图
String result = actionMapping.getResult(resultName);
//重定向到页面
response.sendRedirect(result); } catch (Exception e) {
e.printStackTrace();
} } //根据请求的上下文获取到ActionName
public String getActionName(HttpServletRequest request){
//获取到URI
String uri = request.getRequestURI();
//获取上下文路径
String contextPath = request.getContextPath();
//从上下文中截取ActionPath
String actionPath = uri.substring(contextPath.length());
//获取到ActionName
String actionName=actionPath.substring(,actionPath.lastIndexOf('.')).trim();
return actionName;
} //在加载Servlet的时候就读取配置文件信息
@Override
public void init(ServletConfig config) throws ServletException {
//读取配置信息
String configStr = config.getInitParameter("config");
String[] fileNames=null;
if(configStr==null||configStr.isEmpty()){
fileNames=new String[]{"myframework.xml"};
}else{
fileNames=configStr.split(",");
}
//读取配置文件,将文件中的信息保存到ActionMappingManager中
actionMappingManager=new ActionMappingManager(fileNames);
}
}

第八步:修改web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>MVCServlet</servlet-name>
<servlet-class>servlet.MVCServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>MVCServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>

测试页面(login.jsp)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
<form action="loginAction.action" method="post">
用户名:<input type="text" name="uname"/><br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>

这样我们就完成了一个自定义的MVC框架了

自定义MVC框架的更多相关文章

  1. Struts2 自定义MVC框架

    一.Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形 ...

  2. 第一章 自定义MVC框架

    第一章  自定义MVC框架1.1 MVC模式设计    组成:Model:模型,用于数据和业务的处理          View :视图,用于数据的显示          Controller:控制器 ...

  3. 自定义MVC框架之工具类-模型类

    截止目前已经改造了5个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 自定义MVC框架之工具类-图像处理 ...

  4. 自定义MVC框架之工具类-图像处理类

    截止目前已经改造了4个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 图像处理类: 1,图片加水印处理( ...

  5. 自定义MVC框架之工具类-文件上传类

    截止目前已经改造了3个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 该文件上传类功能如下: 1,允许定制上传的文件类型,文件mime信息,文 ...

  6. Java Web自定义MVC框架详解 (转)

    转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架 ...

  7. 使用Intellij Idea自定义MVC框架

    ---恢复内容开始--- 今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图 ...

  8. springmvc执行原理及自定义mvc框架

    springmvc是spring的一部分,也是一个优秀的mvc框架,其执行原理如下: (1)浏览器提交请求经web容器(比如tomcat)转发到中央调度器dispatcherServlet. (2)中 ...

  9. struts2自定义MVC框架

    自定义MVC:(首先了解Model1和Model2的概念) Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是 ...

随机推荐

  1. angularjs 指令详解 - template, restrict, replace

    通过指令机制,angularjs 提供了一个强大的扩展系统,我们可以通过自定义指令来扩展自己的指令系统. 怎样定义自己的指令呢? 我们通过 Bootstrap UI来学习吧.这个项目使用 angula ...

  2. Qt And MFC UI Layout

    界面布局 起初,计算机的交互是通过输入的代码进行的, 慢慢的有了图形之后, 就开始了图形界面的交互. 目前来说还有语音交互, 视频交互等多媒体的交互. 不管哪一种交互, 最终在计算机的角度都是信号的输 ...

  3. Eclipse 常用快捷键 (动画讲解)

    Eclipse有强大的编辑功能, 工欲善其事,必先利其器, 掌握Eclipse快捷键,可以大大提高工作效率.  编辑相关快捷键 注释          Ctrl + / 快速修复    Ctrl + ...

  4. JavaScript随笔1

    1.NaN不等于NaN 2.判断是不是NaN:isNaN; (强制类型转换) 3.parseInt(3.5) ->3  parseInt(3px)->3 4.pareFloat(3.7)- ...

  5. html中定义标签字母的大小写

    定义和用法: text-transform 属性控制文本的大小写. 值和属性: 值 描述 none 默认.定义带有小写字母和大写字母的标准的文本. capitalize 文本中的每个单词以大写字母开头 ...

  6. MongoDB 分片管理

    在MongoDB(版本 3.2.9)中,分片集群(sharded cluster)是一种水平扩展数据库系统性能的方法,能够将数据集分布式存储在不同的分片(shard)上,每个分片只保存数据集的一部分, ...

  7. 事务复制5: Transaction and Command

    事务复制使用 dbo.msrepl_transactions 和 dbo.MSrepl_commands 存储用于数据同步的Transaction和Command.在replication中,每个co ...

  8. 解密jQuery事件核心 - 委托设计(二)

    第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...

  9. OpenCASCADE BRep vs. OpenNURBS BRep

    OpenCASCADE BRep vs. OpenNURBS BRep eryar@163.com Abstract. BRep short for Boundary Representation. ...

  10. Building OpenCASCADE on Debian

    Building OpenCASCADE on Debian eryar@163.com Abstract. When you are familiar with OpenCASCADE on Win ...