前面说完了Spring、Hibernate,非常自然今天轮到struts了。struts的核心原理就是通过拦截器来处理client的请求,经过拦截器一系列的处理后,再交给Action。以下先看看struts官方的工作原理图:

图1 struts原理图

简单分析一下:首先client发来HttpServletRequest请求,传递给FilerDispatcher(ActionMapper是訪问静态资源(struts的jar文件等)时用的,平时非常少用),然后FilerDispatcher会为我们创建一个ActionProxy,ActionProxy会通过ConfigurationManager获得struts.xml文件里的信息,ActionProxy拥有一个ActionInvocation实例,通过调用ActionInvocation的invoke()方法,来挨个处理Interceptor,最后处理Action,接着Result返回,再逆序经过Interceptor,最后得到HttpServletResponse返回给client。

假设不太明确呢,那就看看以下这张时序图,或许你就懂了:

图2 struts原理时序图

上面的时序图逻辑就比較清晰了,我就只是多解释了。看完struts的原理图,我们还是须要通过代码来进一步了解它详细是怎么实现的。首先,我们须要一个ActionInvocation:

package com.tgb.struts;
import java.util.ArrayList;
import java.util.List; public class ActionInvocation {
List<Interceptor> interceptors = new ArrayList<Interceptor>();
int index = -1;
Action a = new Action(); public ActionInvocation() {
this.interceptors.add(new FirstInterceptor());
this.interceptors.add(new SecondInterceptor());
} public void invoke() {
index ++;
if(index >= this.interceptors.size()) {
a.execute();
}else { this.interceptors.get(index).intercept(this);
}
}
}

我们实现的ActionInvocation是将Interceptor写在里面的,但实际上是通过反射载入的,原理同之前写的Spring与Hibernate的博客,同样的代码就不在这里占用篇幅了,也没啥意思。不知道怎么实现的朋友请查看前面几篇博客。

接下来是我们的Interceptor接口以及两个简单的实现:

package com.tgb.struts;

public interface Interceptor {
public void intercept(ActionInvocation invocation) ;
} package com.tgb.struts; public class FirstInterceptor implements Interceptor { public void intercept(ActionInvocation invocation) {
System.out.println("FirstInterceptor Begin...");
invocation.invoke();
System.out.println("FirstInterceptor End...");
} } package com.tgb.struts; public class SecondInterceptor implements Interceptor { public void intercept(ActionInvocation invocation) {
System.out.println("SecondInterceptor Begin...");
invocation.invoke();
System.out.println("SecondInterceptor End...");
} }

然后就是我们的Action:

package com.tgb.struts;

public class Action {
public void execute() {
System.out.println("Action Run...");
}
}

最后是我们的client调用:

package com.tgb.struts;

public class Client {
public static void main(String[] args) {
new ActionInvocation().invoke();
}
}

差点忘了,还有我们最后的运行结果:

FirstInterceptor Begin...
SecondInterceptor Begin...
Action Run...
SecondInterceptor End...
FirstInterceptor End...

通过上面的运行结果,我们能够非常清晰的看到,请求来的时候会依照顺序被全部配置的拦截器拦截一遍,然后返回的时候会依照逆序再被拦截器拦截一遍。这跟数据结构中的“栈”非常相似(FIFO-先进先出),数据结构我不太懂,或许这样比喻有些不妥。各位依据自己的认识理解吧。

近期一直在研究这三大框架,折腾半天它们都离不开集合,离不开反射。事实上它们道理都是想通的,搞懂一个,其它的也就非常好懂了。等着吧,早晚咱们自己写一个更好用的。

最佳新秀SSH十六Struts2它是如何工作的内部的更多相关文章

  1. 二十六个月Android学习工作总结【转】

    原文:二十六个月Android学习工作总结 1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍.     2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该 ...

  2. 二十六个月Android学习工作总结

    1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍. 2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该功能的运行过程写出来. 3.要有自己的知识库,可以是 ...

  3. 第十六章、例行性工作排程 (crontab)

    1. 什么是例行性工作排程 1.1 Linux 工作排程的种类: at, crontab 1.2 Linux 上常见的例行性工作 2. 仅运行一次的工作排程 2.1 atd 的启动与 at 运行的方式 ...

  4. 二十六:Struts2 和 spring整合

    二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...

  5. Struts2(十六篇)

    (一)Struts2框架概述 (二)Struts2配置文件 (三)Struts2的Action(简单讲解版) (四)Struts2的Action(深入讲解版) (五)Struts2处理结果管理 (六) ...

  6. 菜鸟玩云计算之十六:Ubuntu14.04上创建的虚拟机迁移到RHEL6.4

    菜鸟玩云计算之十六:Ubuntu14.04上创建的RHEL6.4虚拟机迁移到RHEL6.4主机上 RHEL6.4 Server作为虚拟机的HOST,执行以下的命令检查配置和安装相关软件: # egre ...

  7. J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用

    J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用   spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...

  8. Spring Boot(十六):使用Jenkins部署Spring Boot

    Spring Boot(十六):使用Jenkins部署Spring Boot jenkins是devops神器,介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署 ...

  9. centos linux系统日常管理3 服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,curl,ping ,telnet,traceroute ,dig ,nc,nmap,host,nethogs 第十六节课

    centos linux系统日常管理3  服务管理ntsysv,chkconfig,系统日志rsyslog,last ,lastb ,exec,xargs,dmesg,screen,nohup,cur ...

随机推荐

  1. Linux编程return与exit区别

    Linux编程return与exit区别 exit  是用来结束一个程序的执行的,而return只是用来从一个函数中返回. return return 表示从被调函数返回到主调函数继续执行,返回时可附 ...

  2. MyCAT部署及实现读写分离(转)

    MyCAT是mysql中间件,前身是阿里大名鼎鼎的Cobar,Cobar在开源了一段时间后,不了了之.于是MyCAT扛起了这面大旗,在大数据时代,其重要性愈发彰显.这篇文章主要是MyCAT的入门部署. ...

  3. fzu2150(bfs)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2150 题意:在任意两处点火,求最短时间烧光所有草堆. 分析:由于n,m比较小,将所有草堆坐标记录下来,然后暴力 ...

  4. 自己动手写了第三阶段的处理器——教学OpenMIPS处理器蓝图

    我们会继续上传新书<自己动手写处理器>(未公布).今天是第十条.我每星期试试4 从本章開始将一步一步地实现教学版OpenMIPS处理器.本章给出了教学版OpenMIPS的系统蓝图,首先介绍 ...

  5. Django URL 命名空间

    https://docs.djangoproject.com/en/1.5/topics/http/urls/#introduction 译文: URL 命名空间 简介: 当你需要部署一个应用的多个实 ...

  6. MongoDB 基础命令——数据库表的增删改查——遍历操作表中的记录

    分组排序查询最大记录 //对 "catagory" 不等于 null 的数据进行分组查询,且查询结果倒序 db.getCollection('userAccount').aggre ...

  7. HDOJ 5276 YJC tricks time multimap

    multimap的使用 YJC tricks time Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/262144 K ...

  8. openwrt教程 第一章 物联网&amp;openwrt开发概述

    1.1 我们的宗旨 互联网.移动互联网的时代已经过去,物联网的时代已经来临!2014年,是物联网元年,2016年,物联网将达到高潮!为了迎接该潮流,我们工作室(F403科技创意室:http://f40 ...

  9. iOS很重要的 block回调

    刚刚进入ios开发行业,发现开发中要用到大量的block回调,由此可见它的重要性.学习它之前我也是网上找的资料,推荐这篇文章http://blog.csdn.net/mobanchengshuang/ ...

  10. 线段树(单点更新and成段更新)

    线段树需要的空间. 区间为1-->n 假设是一棵完全二叉树,且树高为i. 完全二叉树性质:第i层最多有2^(i-1)个结点. 那么 2^(i-1) = n;     i = log2(n)  + ...