菜鸟学SSH(十六)——Struts2内部是如何工作的
前面说完了Spring、Hibernate,很自然今天轮到struts了。struts的核心原理就是通过拦截器来处理客户端的请求,经过拦截器一系列的处理后,再交给Action。下面先看看struts官方的工作原理图:
图1 struts原理图
简单分析一下:首先客户端发来HttpServletRequest请求,传递给FilerDispatcher(ActionMapper是访问静态资源(struts的jar文件等)时用的,平时很少用),然后FilerDispatcher会为我们创建一个ActionProxy,ActionProxy会通过ConfigurationManager获得struts.xml文件中的信息,ActionProxy拥有一个ActionInvocation实例,通过调用ActionInvocation的invoke()方法,来挨个处理Interceptor,最后处理Action,接着Result返回,再逆序经过Interceptor,最后得到HttpServletResponse返回给客户端。
如果不太明白呢,那就看看下面这张时序图,也许你就懂了:
图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...");
}
}
最后是我们的客户端调用:
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内部是如何工作的的更多相关文章
- 最佳新秀SSH十六Struts2它是如何工作的内部
前面说完了Spring.Hibernate,非常自然今天轮到struts了.struts的核心原理就是通过拦截器来处理client的请求,经过拦截器一系列的处理后,再交给Action.以下先看看str ...
- 菜鸟学SSH(六)——Spring事务管理
Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.Tran ...
- 二十六个月Android学习工作总结【转】
原文:二十六个月Android学习工作总结 1.客户端的功能逻辑不难,UI界面也不难,但写UI花的时间是写功能逻辑的两倍. 2.写代码前的思考过程非常重要,即使在简单的功能,也需要在本子上把该 ...
- 菜鸟学SSH(三)——Struts2国际化自动检测浏览器语言版
前几天发了一篇Struts国际化的博客——<菜鸟学习SSH(二)——Struts2国际化手动切换版>,有网友提了一个意见,见下图: 于是就有了下面修改的版本: web.xml <?x ...
- 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理
之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...
- 菜鸟学SSH(四)——Struts2拦截器
什么是拦截器 拦截器(Interceptor)是Struts 2的一个强有力的工具,有许多功能都是构建于它之上,如国际化(前两篇博客介绍过).转换器,校验等. 拦截器是动态拦截Action调用的对象. ...
- 菜鸟学SSH(二)——Struts2国际化手动切换版
国际化(internationalization,i18n)和本地化(localization,l10n)指让产品(出版物,软件,硬件等)能够适应非本地环境,特别是其他的语言和文化.程序在不修改内部代 ...
- 菜鸟学SSH(十八)——Hibernate动态模型+JRebel实现动态创建表
项目用的是SSH基础框架,当中有一些信息非常相似,但又不尽同样.假设每个建一个实体的话,那样实体会太多.假设分组抽象,然后继承,又不是特别有规律.鉴于这样的情况.就打算让用户自己配置要加入的字段,然后 ...
- 菜鸟学SSH(十)——Hibernate核心接口
在使用Hibernate的时候,我们通常都会用的Configuration.SessionFactory.Session.Transaction.Query和Criteria等接口.通过这些接口可以, ...
随机推荐
- Shell脚本学习之sed详解
在编写shell脚本的过程中,我们经常需要使用sed流编辑器和awk对文本文件进行处理. 一.什么是sed? sed 是一种在线编辑器,它一次处理一行内容.sed是非交互式的编辑器.它不会修改文件,除 ...
- java非web应用修改 properties/xml配置文件后,无需重启应用即可生效---自动加载
实现时主要使用Commons-Configuration.jar包,还需要commons-lang,disgestor,beanutils,collections等, package propFile ...
- Java概述与开发环境
1.Java语言既是编译又是解释型的特点 Java没有设计成编译型语言,因为编译型语言效率高, 但可移植性差. Java也没有设计成纯解释型的语言, 因为解释型效率太低. 编译成class文件, 解释 ...
- hduoj1073--Online Judge
做道题,并没有太多的技巧,关键在与对Accepted,presented error 和wa的判断,第一步如果两者完全一样,那么很定是AC了 ,否则如果去掉多余换行,空格,制表后还有不同说明是数据 不 ...
- keras中的loss、optimizer、metrics
用keras搭好模型架构之后的下一步,就是执行编译操作.在编译时,经常需要指定三个参数 loss optimizer metrics 这三个参数有两类选择: 使用字符串 使用标识符,如keras.lo ...
- 给我一对公钥和私钥,我就能破解此RSA
RSA密码系统如果暴露了一套公钥和私钥,那么这套密码系统就全部失效了.因为根据公钥和私钥可以完成大整数的分解.暴露了两个质数. 记公钥为e,私钥为d,因为ed%phi=1,所以就得到了一个k=ed-1 ...
- Python学习笔记(八)—— 使用dict和set
一.dict 1.定义: Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度 2.优势: di ...
- HDU 4632 Palindrome subsequence (区间DP)
Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65535 K (Java/ ...
- 微信支付中的jsapi返回提示信息
jsapi中跳转到微信支付中触发的方法是js中的getBrandWCPayRequest方法. 改方法中的返回结果msg提示信息如下: err_msg:get_brand_wcpay_request: ...
- [bug]WCF 内存入口检查失败 Memory gates checking failed
bug描述 异常信息:内存入口检查失败,因为可用内存(xxx 字节)少于总内存的 xx%.因此,该服务不可用于传入的请求.若要解决此问题,请减少计算机上的负载,或调整 serviceHostingEn ...