最佳新秀SSH十六Struts2它是如何工作的内部
前面说完了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它是如何工作的内部的更多相关文章
- 二十六个月Android学习工作总结【转】
原文:二十六个月Android学习工作总结 1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍. 2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该 ...
- 二十六个月Android学习工作总结
1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍. 2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该功能的运行过程写出来. 3.要有自己的知识库,可以是 ...
- 第十六章、例行性工作排程 (crontab)
1. 什么是例行性工作排程 1.1 Linux 工作排程的种类: at, crontab 1.2 Linux 上常见的例行性工作 2. 仅运行一次的工作排程 2.1 atd 的启动与 at 运行的方式 ...
- 二十六:Struts2 和 spring整合
二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...
- Struts2(十六篇)
(一)Struts2框架概述 (二)Struts2配置文件 (三)Struts2的Action(简单讲解版) (四)Struts2的Action(深入讲解版) (五)Struts2处理结果管理 (六) ...
- 菜鸟玩云计算之十六:Ubuntu14.04上创建的虚拟机迁移到RHEL6.4
菜鸟玩云计算之十六:Ubuntu14.04上创建的RHEL6.4虚拟机迁移到RHEL6.4主机上 RHEL6.4 Server作为虚拟机的HOST,执行以下的命令检查配置和安装相关软件: # egre ...
- J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用
J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用 spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...
- Spring Boot(十六):使用Jenkins部署Spring Boot
Spring Boot(十六):使用Jenkins部署Spring Boot jenkins是devops神器,介绍如何安装和使用jenkins部署Spring Boot项目 jenkins搭建 部署 ...
- 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 ...
随机推荐
- [Android学习笔记]自定义控件的使用
自定义控件时,最好抽象得彻底,并且编写需严谨,因为可能程序中多处都会引用到它,或者提供给团队中的其他人使用. 其一般步骤为: 1.创建控件的类文件,定义其功能逻辑.一般继承自现有控件或者View2.在 ...
- Eclipse乱码怎么办
Eclipse里设置编码有三个层次:全局.工程.文件. 文件的编码会覆盖工程的编码,工程的编码会覆盖全局的编码. 我猜测:虽然你的工程编码更改为GBK,但只对新建文件有效. 如果工程中旧有的文件是UT ...
- swift-switch使用方法
// Playground - noun: a place where people can play import UIKit //--------------------------------- ...
- Linq 数据操作,两个数组求差、交集、并集
int[] a = { 1, 2, 3, 4, 5, 6, 7 }; int[] b = { 4, 5, 6, 7, 8, 9, 10 }; int[] c = { 1, 2, 3, 3, 4, 1, ...
- Windows Phone开发人员必看资料
win phone开发必看资料,下载地址收藏啦!收藏后可有选择性的下载,希望大家喜欢! 完整附件下载:http://down.51cto.com/data/414417 附件预览: Windows E ...
- SVNKIT的SVNCommitClient的doMkDir的操作
package com.repositoryclient.svnoptions; import java.io.File; import org.tmatesoft.svn.core.SVNCommi ...
- uva 10066 The Twin Towers (最长公共子)
uva 10066 The Twin Towers 标题效果:最长公共子. 解题思路:最长公共子. #include<stdio.h> #include<string.h> # ...
- for循环中一个不容小觑的问题
for(int i=1;i<=100;i++) 作为程序猿,我们很喜欢使用这种for循环. 可是,当中隐含着一个重要的问题. 过多的编程经历可能使我们的思维产生了一些误解,在上面的for循环中, ...
- c#和UDP SOCKET广播
server: Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,ProtocolType.Udp); // ...
- python学习笔记之一:列表与元组
最近在看<python基础教程>(基于python2.x),下面总结一下第二章列表与元组的知识: 在这章中引入了数据结构的概念.数据结构是通过某种方式组织在一起的数据元素的集合.在pyth ...