自定义MVC框架
我们在学习自定义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框架的更多相关文章
- Struts2 自定义MVC框架
一.Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形 ...
- 第一章 自定义MVC框架
第一章 自定义MVC框架1.1 MVC模式设计 组成:Model:模型,用于数据和业务的处理 View :视图,用于数据的显示 Controller:控制器 ...
- 自定义MVC框架之工具类-模型类
截止目前已经改造了5个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 自定义MVC框架之工具类-图像处理 ...
- 自定义MVC框架之工具类-图像处理类
截止目前已经改造了4个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 图像处理类: 1,图片加水印处理( ...
- 自定义MVC框架之工具类-文件上传类
截止目前已经改造了3个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 该文件上传类功能如下: 1,允许定制上传的文件类型,文件mime信息,文 ...
- Java Web自定义MVC框架详解 (转)
转自:http://blog.csdn.net/jackfrued/article/details/42774459 最近给学生讲Java Web,希望他们能够在学完这部分内容后自己实现一个MVC框架 ...
- 使用Intellij Idea自定义MVC框架
---恢复内容开始--- 今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图 ...
- springmvc执行原理及自定义mvc框架
springmvc是spring的一部分,也是一个优秀的mvc框架,其执行原理如下: (1)浏览器提交请求经web容器(比如tomcat)转发到中央调度器dispatcherServlet. (2)中 ...
- struts2自定义MVC框架
自定义MVC:(首先了解Model1和Model2的概念) Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是 ...
随机推荐
- ASP.NET安全
ASP.NET 安全 概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 ...
- Some practices to write better C#/.NET code(译)
C#(.NET)中有关编码的一些建议,原文地址:http://www.codeproject.com/Articles/539179/Some-practices-to-write-better-Cs ...
- 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介
注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...
- 完全使用一组 DSL 来操作 Grid 控件
最近尝试了一下将 XtraGrid 的初始化工作封装成内部 DSL,例如一个普通的基础数据的增删改查操作的代码会像下面这样: public partial class UserForm : XtraF ...
- 移动APP服务端设计开发注意要点
2014年,移动APP的热度丝毫没有减退,怎么为您的移动端app设计良好的服务器端接口(API)呢? 下面谈谈我个人的一些想法. 2014年,移动APP的热度丝毫没有减退,并没有像桌面软件被WEB网站 ...
- Java伪界面操作数据库的小实例
首先在Mysql中有两个表fruit和login: package com.zuoye; import java.sql.*; import java.util.*; public class Tes ...
- gulp启动一个小型web服务器配置&browserify(require)
var gulp = require('gulp'), connect = require('gulp-connect'), // 运行live reload服务器 browserify = requ ...
- 【WP 8.1开发】How to 图像处理
在今天的吹牛节目开始之前,先交代一件事: 关于玩WP 8.1开发所使用的VS版本问题.对版本的要求是2013的Update2,这是最低要求,只要是这个版本或以上都可以,而update3,update4 ...
- [C#]想说一说嵌套数组
今天早上,随感而发,随便写了点东西.结果下午的时候看了看评论,吓我一跳.估计是不是写代码的人看散文看得太少了,还是因为现在的人读的书太少了,似乎有有些大惊小怪. 关于Y美女,我声明一下,尽管她很脱俗, ...
- Building OpenCASCADE on Debian
Building OpenCASCADE on Debian eryar@163.com Abstract. When you are familiar with OpenCASCADE on Win ...