Struts2 自定义MVC框架
一、Model1与Model2:
Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起。
Model2:Model2是在Model1的基础上,将业务逻辑的代码分离开来,单独形成一个Servlet,Model2也是基于MVC开发
二、MVC设计模式:
由3个部分组成,各部分作用如下:
Model:模型,主要用于数据和业务的处理
View:视图,用于数据的显示
Controller:控制器,用于进行流程控制
MVC设计模式的特点:
①一个模型可以对应多个视图
②显示与逻辑控制的分离
③分层控制,减轻了代码间的耦合
自定义MVC框架只需dom4j.jar包即可!

三、准备XML文档Framework.xml
注意点:
<!-- ELEMENT 表示元素 -->
<!-- ATTLIST 表示属性 -->
<!-- CDATA 表示字符串类型 -->
<!-- REQUIRED 表示此属性必须的写 -->
<!-- *代表多个 -->
<!-- IMPLIED 表示此属性可写 -->

<!DOCTYPE Framework[
<!ELEMENT Framework (actions)>
<!ELEMENT actions (action*)>
<!ELEMENT action (result*)> <!ATTLIST action name CDATA #REQUIRED
class CDATA #REQUIRED
> <!ATTLIST RESULT name CDATA #IMPLIED
redirect (true|false) "false"
> ]> <Framework>
<actions>
<action name="loginAction" class="cn.happy.action.LoginAction">
<result name="success">success.jsp</result>
<result name="login">index.jsp</result>
</action>
</actions>
</Framework>


四、定义自己的Action接口,用于存放结果集和要执行的方法

public interface Action {
//定义两个静态字符串常量(逻辑视图名)
public static final String SUCCESS="success";
public static final String LOGIN="login";
//定义一个抽象方法execute
public String execute(HttpServletRequest request,HttpServletResponse response)throws Exception;
}

五、定义ActionMapping类用于存放Action节点,即一个ActionMapping类可以视为配置文件中的一个action节点

public class ActionMapping {
//根据action节点中的属性 以及action节点中的<result></result>节点定义三个私有属性
private String name;//action的名称
private String classname;//action对应程序中的类
private Map<String,String> results=new HashMap<String,String>();
//向results集合中添加数据的方法
public void addResult(String name,String value){
results.put(name, value);
}
//根据名称获取的方法
public String getResults(String name){
return results.get(name);
}
public Map<String, String> getResults() {
return results;
}
public void setResults(Map<String, String> results) {
this.results = results;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}

六、定义ActionMappingManager类用于管理ActionMapping,并通过dom4j解析Framework.xml配置文件。从而获取根节点,以及actions节点,并通过for循环遍历actions节点下的action节点拿到name和class的属性值,由于一个action节点下有多个result节点 及遍历action下所有的result节点,分别存入到actionMapping中的双列集合中,最后得到所有action节点的集合

public class ActionMappingManager {
//actionMapping类的集合
private Map<String,ActionMapping> maps=new HashMap<String,ActionMapping>();
public ActionMapping getActionMapping(String name){
return maps.get(name);
}
//解析src下所有配置文件
public ActionMappingManager(String[]files){
for (String filename : files) {
init(filename);
}
}
//创建初始化方法,使用dom4j解析配置文件
public void init(String path){
try {
//getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据
InputStream is=this.getClass().getResourceAsStream("/"+path);
//解析XML
Document doc=new SAXReader().read(is);
//获取根节点
Element root = doc.getRootElement();
//获取actions节点
Element actions =(Element)root.elementIterator("actions").next();
//使用for循环来
//遍历actions节点下的所有action节点
for (Iterator<Element> action=actions.elementIterator("action");action.hasNext();) {
//获取到action节点
Element actionnext = action.next();
//分别获取到action节点中的name属性和class属性
String name=actionnext.attributeValue("name");
String classname=actionnext.attributeValue("class");
//将以上两个属性保存到ActionMapping类中
ActionMapping mapp=new ActionMapping();
mapp.setClassname(classname);
mapp.setName(name);
//由于一个action节点下有多个result节点 遍历action下所有的result节点
for (Iterator<Element> result=actionnext.elementIterator("result");result.hasNext();){
//获取到result节点
Element resultnext = result.next();
//提取result节点的name属性值和result节点中的值
String resultname= resultnext.attributeValue("name");
String resultvalue= resultnext.getText();
//将其分别存入到actionMapping中的双列集合中去,方便调用actionMapping类(actionMapping类中就有数据了!)
mapp.addResult(resultname, resultvalue);
}
//得到所有action节点的集合
maps.put(mapp.getName(), mapp);
}
} catch (Exception e) {
}
}

七、使用反射机制根据字符串类型的类名获取到具体的类--ActionManager

public class ActionManager {
public static Action getActionClass(String classname){
Class clazz=null;
Action action=null;
//获取当前线程的加载类
try {
clazz=Thread.currentThread().getContextClassLoader().loadClass(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if(clazz==null){
try {
//如果该线程中没有,那么使用class.forname方法获取
clazz=Class.forName(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
if(action==null){
//将获取到的类型转换为action,调用无参构造函数,某种程度上相当于new,不过new需要指定类型
try {
action =(Action)clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return action;
}

八、定义Servlet类,详情见注释!注意点在web.xml中添加 <load-on-startup>节点,让程序一开始就初始化servlet


public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
ActionMappingManager man=null;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取到ActionMapping对象
ActionMapping actionMapping=man.getActionMapping(getname(request));
//获取action接口利用反射机制
Action action = ActionManager.getActionClass(actionMapping.getClassname());
try {
String message=action.execute(request, response);
String results=actionMapping.getResults(message);
response.sendRedirect(results);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取请求路径名
public String getname(HttpServletRequest request)
{
//项目+请求地址
String requestURI =request.getRequestURI();
//项目名称
String contextPath=request.getContextPath();
//具体的请求
String path=requestURI.substring(contextPath.length());
String filename=path.substring(1,path.lastIndexOf(".")).trim();
return filename;
}
//重写servlet的init方法,让程序一开始就初始化servlet
//由于一个项目src根目录下有可能有多个配置文件,不止一个,所以逐个解析
@Override
public void init(ServletConfig config) throws ServletException {
//初始化参数信息
String filename = config.getInitParameter("config");
String [] filenames=null;
if(filename==null){
//如果没有别的参数信息,就将已经配好的放入数组中
filenames=new String[]{"Framework.xml"};
}
else{
//拆分配置文件名称字符串
filenames=filename.split(",");
}
//使用init方法初始化
man=new ActionMappingManager(filenames);
}

九、业务逻辑Action并实现Action接口,并重写自定义的execute方法

public class LoginAction implements Action{
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String name=request.getParameter("name");
String pwd=request.getParameter("pwd");
if(name.equals("1")&&pwd.equals("1")){
return SUCCESS;
}
else{
return LOGIN;
}
}

十、编写登录界面

<body>
<form action="loginAction.action" method="post">
姓名:<input type="text" name="name"/><br/>
密码:<input type="text" name="pwd"/><br/>
<input type="submit" value="登录">
</form>
</body>

实现效果:


Struts2 自定义MVC框架的更多相关文章
- struts2自定义MVC框架
自定义MVC:(首先了解Model1和Model2的概念) Model1与Model2: Model1:就是一种纯jsp开发技术,将业务逻辑代码和视图渲染代码杂糅在一起. Model2:Model2是 ...
- 自定义MVC框架
我们在学习自定义MVC框架的时候常常会听到Model1 ,Model2和MVC.那么什么是Model1 什么是Model2什么又是MVC呢? 什么是Model1? Model1就是一种纯jsp开发技术 ...
- 第一章 自定义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)中 ...
随机推荐
- 为什么volatile不能保证原子性而Atomic可以?
在上篇<非阻塞同步算法与CAS(Compare and Swap)无锁算法>中讲到在Java中long赋值不是原子操作,因为先写32位,再写后32位,分两步操作,而AtomicLong赋值 ...
- php调用COM组件
PHP 开启COM组件 1.先到PHP.INI中打开COM选项,com.allow_dcom = true 2.我这里的环境是PHP5.4.7,PHP 5.4.5后,com/dotnet 模块已经成了 ...
- linux 下添加库的加载路径的方式
linux 下有两种添加加载库路径的方式: 1.修改环境变量: export LD_LIBRARY_PATH=path_name 2.修改配置文件 修改 /etc/ld.so.conf 的内容在最后添 ...
- 数据见50条常用sql
问题及描述: --1.学生表 Student(Sid,Sname,Sage,Ssex) --Sid 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Course ...
- BZOJ 1044 木棍分割 解题报告(二分+DP)
来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limi ...
- 如何在MFC界面开发中响应Button按钮的Down和Up事件
通过尝试有两种方案可以解决这个问题,第一种方案是通过PreTranslateMessage函数在调度消息之前对消息类型进行筛选,第二种方案是重载CButton类,在重载后的类CForTestButto ...
- IT基础架构规划方案之实际网络设计案例
根据某集团总部新办公大楼.厂房和分支机构(店面)的情况,以及IT部门对网络节点数.网络应用和分支机构(店面)的初步规划,对企业的总体网络拓扑结构进行设计,如下图. 设备选型和部署参考: 类型 设备选型 ...
- big-endian和little-endian
1.故事的起源 "endian"这个词出自<格列佛游记>.小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开 ...
- 可轮播滚动的Tab选项卡
前段时间有试着搭建个后台主题ui框架,有用到可支持滚动的Tab选项卡,模仿着H+后台主题ui框架中的代码造轮子改造了下,可惜代码在公司,不能把代码外发出来(感觉这样被限制了很多,对于这样的公司没办法, ...
- 自定义加载loading view动画组件的使用。
在github上找的一个有点酷炫的loading动画https://github.com/Fichardu/CircleProgress 我写写使用步骤 自定义view(CircleProgress ...