Struct2 拦截器
拦截器的整个过程
程序是在执行Action之前调用的拦截器,整个过程是这样子的

这里面注意两个问题:
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
ActionMapping mapping) throws ServletException { Map<String, Object> extraContext = createContextMap(request, response, mapping, context); // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
try { Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
这个字段就是"struts.valueStack"
// if the ActionMapping says to go straight to a result, do it!
if (mapping.getResult() != null) { } else {
proxy.execute();
} } catch (ConfigurationException e) { }
就看里面标记的这几句,这个方法的作用设置好valueStack,然后放到request范围里
也就是说通过request可以得到valueStack对象;
so,在视图上拿valueStack对象的方式就有以下两种:
1.request.getAttribute()
2.ongl: #request.structs.valueStack
第二个是循环Interceptor的问题,每一个Interceptor里面其实都调用了invoke方法,
那么这个调用是怎么实现的呢,
现在做一个模拟就明白了
拦截器原理模拟
使用最简单的java工程做实验
然后定义一个Action,表示最后要执行的东东
public class Action {
public void execute() {
System.out.println("execute!");
}
}
然后最重要的是定义一个ActionInvocation
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());
} //首先遍历每一个拦截器,当遍历完了之后,执行Action的方法
public void invoke() {
index ++;
if(index >= this.interceptors.size()) {
a.execute();
}else { this.interceptors.get(index).intercept(this);
}
}
}
先定义一个接口,相当于拦截器
public interface Interceptor {
public void intercept(ActionInvocation invocation) ;
}
然后两个类实现这个接口
public class FirstInterceptor implements Interceptor {
public void intercept(ActionInvocation invocation) {
System.out.println(1);
//在里面又返回调用ActionInvocation 的Invoke方法
invocation.invoke();
System.out.println(-1);
}
}
public class SecondInterceptor implements Interceptor {
public void intercept(ActionInvocation invocation) {
System.out.println(2);
invocation.invoke();
System.out.println(-2);
}
}
定义主方法
public class Main {
public static void main(String[] args) {
new ActionInvocation().invoke();
}
}
最后的结果是
1
2
execute!
-2
-1
这里面最关键的地方就是转来转去用的都是同一个ActionInvocation 对象
流程大概是:
实线表示直接调用,虚线表示方法返回
上图是完整的调用过程
因为ActionInvocation调用Second是在First内部,只是转折了一下,所以可以理解为First调用了Second

通过Struct官方的图来理解整个过程

最主要的思想是在执行Action之前拦一下,在执行之后拦一下
从这个图中,也可以理解什么叫做AOP,面向切面编程
本来有没有拦截器Struct方法都能执行
但是突然冒出一个拦截器有种在执行之前切上一刀的感觉
拦截器的有点是可插入,可抽回
拦截器可以用在敏感字符处理,在提交的数据进入服务器的时候,首先检查数据是不是有敏感字符
还可以用在权限上面
我们想一下如果没有拦截器怎么做权限
有两种方式:
一个是在Action类中的exection方法里面进行判断
一个是在Jsp的头的session里面进行判断
这样做是要在每一个Action和JSP里面都要写的啊
当然权限判断现在有很好的spring security
定义自己的Struct拦截器
这个其实就是重复造成轮子的过程,只要看看别人的轮子是怎么造出来的就可以了。
首先:定义一个MyInterceptor类
package com.bjsxt.interceptor; import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor; public class MyInterceptor implements Interceptor { public void destroy() {
// TODO Auto-generated method stub } public void init() {
// TODO Auto-generated method stub } public String intercept(ActionInvocation invocation) throws Exception {
long start = System.currentTimeMillis();
String r = invocation.invoke();
long end = System.currentTimeMillis();
System.out.println("action time = " + (end - start));
return r;
} }
然后要把这个拦截器加到配置里面
在Struct里面,默认拦截器都是放在/struts-default.xml 里面,当然我们不能改人家的代码。
修改Struct.xml
<package name="test" namespace="/" extends="struts-default">
首先声明这个拦截器
<interceptors>
<interceptor name="my" class="com.bjsxt.interceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="test" class="com.bjsxt.action.TestAction">
<result>/test.jsp</result>
<interceptor-ref name="my"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
在实际开发过程中,自定义拦截器实际上是很少很少用到的。一方面,Struct已经为我们写出来很多拦截器,另一方面,一旦我们自定义了拦截器,那么我们的代码就和Struct绑定上了,以后如果再换成其他架构基本上是无法实现的。
Struct2 拦截器的更多相关文章
- Struct2 自定义拦截器
1 因为struct2 如文件上传,数据验证等功能都是由系统默认的 defalutStack中的拦截器实现的,所以我们定义拦截器需要引用系统默认的defalutStack 这样才不会影响struct2 ...
- Spring Aop、拦截器、过滤器的区别
Filter过滤器:拦截web访问url地址.Interceptor拦截器:拦截以 .action结尾的url,拦截Action的访问.Spring AOP拦截器:只能拦截Spring管理Bean的访 ...
- Struts2 (四) — 拦截器
一.拦截器 1.概述 1.1什么是拦截器 在struts2中,拦截器(Interceptor)是用来动态拦截Action执行的对象. 拦截器有点类似以前Servlet阶段的Filter(过滤器 ...
- 6. ModelDriven拦截器、Preparable 拦截器
1. 问题 Struts2 的 Action 我们将它定义为一个控制器,但是由于在 Action 中也可以来编写一些业务逻辑,也有人会在 Action 输入业务逻辑层. 但是在企业开发中,我们一般会将 ...
- springmvc的拦截器
什么是拦截器 java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...
- Struts的拦截器
Struts的拦截器 1.什么是拦截器 Struts的拦截器和Servlet过滤器类似,在执行Action的execute方法之前,Struts会首先执行Struts.xml中引用的拦截器,在执行完所 ...
- Struts2拦截器的执行过程浅析
在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...
- 学习SpringMVC——拦截器
拦截器,顾名思义就是用来拦截的. 那什么是拦截,又为什么要拦截.对于Spring MVC来说,拦截器主要的工作对象就是用户的请求,拦截下来之后,我们可以在拦截的各个阶段悉心呵护[为所欲为].常见的比如 ...
- alias拦截器的使用
在SSH项目中,有时需要由一个Action跳转到另一个Action.有两种方式可以实现Action之间的跳转,一种是chain,另一种是redirectAction,这两种方式之间的区别是chain是 ...
随机推荐
- 移动web经验积累
1.从最小宽度时候开发,调试到iphone4来开发 2.宽度百分比,高度由具体内容决定, 3.文字需要设置最大高度,溢出隐藏 white-space: nowrap; text-overflow: e ...
- CentOS使用sudo提示用户不在sudoers文件中的解决方法
1切换到root用户[linux@localhost ~]$ su root密码:[root@localhost ~]# 2查看/etc/sudoers文件权限,如果只读权限,修改为可写权限 [roo ...
- Android 自定义View实现单击和双击事件
自定义View, 1. 自定义一个Runnable线程TouchEventCountThread , 用来统计500ms内的点击次数 2. 在MyView中的 onTouchEvent 中调用 上面 ...
- 网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词.
网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词. 因为自己写了一个磁力搜索网站Btgoogle,准备进行优化一下,需要分析其他的网站的优化情况. Java的Jsoup类库和PHP的 ...
- shell编程的一些例子4
bash支持一维数组 1.数组定义: name= (value1,value2...valueN) value形如[[subscript]=]string [subscript]= 是可选项 如果没 ...
- bzoj3667: Rabin-Miller算法
Description Input 第一行:CAS,代表数据组数(不大于350),以下CAS行,每行一个数字,保证在64位长整形范围内,并且没有负数.你需要对于每个数字:第一,检验是否是质数,是质 ...
- ASP.NET State Service服务
ASP.NET State Service服务是用来管理 Session 的,正常来说,Session 位于IIS进程中(其实可以理解成在服务器的内存中),当IIS重启或程序池回收会自动清空Sessi ...
- 机器学习的数学基础(1)--Dirichlet分布
机器学习的数学基础(1)--Dirichlet分布 这一系列(机器学习的数学基础)主要包括目前学习过程中回过头复习的基础数学知识的总结. 基础知识:conjugate priors共轭先验 共轭先验是 ...
- Dynamips/Dynagen模拟CISCO路由环境
今天将<网络互连技术>--路由,交换与远程访问实训教程的实验书拿出来了看了部门. 搭建了一个基于DYNAGEN的虚拟环境. 归纳一下大约步骤: ~~~~~~~~~~~~~~ 一,在WIND ...
- http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/
http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/