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是 ...
随机推荐
- 欢迎使用skymvc框架,简单易用的php框架
skymvc是一款轻量.简单易用的php mvc框架,经过多个项目实践改良. 特点: 1.mvc架构 2.m.v.c之间可以互相调用 3.简单的路由控制 R("/index.php" ...
- 【 java版坦克大战--绘图技术】 绘制坦克
通过上一节,我们学会的用java绘图.那现在就用java绘制自己坦克. 首先通过分析坦克由这几部分组成.如图 各个部件的长宽如图.15,10为圆心. /** * 坦克游戏的1.0版 * 1.画出坦克 ...
- HTML5:一个拖拽网页元素的例子
关键字:HTML5, Drag&Drop, JavaScript, CSS 运行环境:Chrome <!DOCTYPE html> <html> <head> ...
- IOS多线程之NSThread
参考:http://blog.csdn.net/totogo2010/article/details/8010231 1 简介 NSThread: 优点:NSThread 比其他两个轻量级 缺点:需要 ...
- 编程范式感想(一)——在C中进行对模板功能的实现
最近一直在看网易公开课上的编程范式的公开课,斯坦福的教授讲的真的非常到位,感觉还是要好好学习下C还有汇编,熟悉下计算机的内存机制什么的. 大家都知道关于模板或者说范式的问题,基本在很多高级语言上都有实 ...
- 关于How,刷墙和亲戚
对于需求而言,最宏观的概念是六字诀: Who->Where->Which->How->End->Effect:谁(Who)在什么地方(Where),对那个对象(Which ...
- C++默认参数值函数
1.默认参数值的函数 C++语言允许在定义函数时给其中或某些形式参数(形参)指定默认值,方法就是在相应的形参后面写上“=默认值”,如果省略了对应位置上的实参的值,则在执行被调函数时以该形参的默认值进行 ...
- 21个很棒的jQuery分页插件下载
分页是指将一个大内容划分为各种不同的页面,因此网站的分页是一个很重要的部分,必须让内容有组织性和易于访问.分页有各两种不同的方式,手动跟自动.最受欢迎简单和广泛的方法是jQuery插件.下面我们收集了 ...
- 一个简单的DDraw应用程序2
//------------------------------------------------------------------------- // 文件名 : 6_1.cpp// 创建者 : ...
- 解决wordpress上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值。
上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值. 解决方法:修改/etc/php5/apache2/php.ini文件中的 post_max_size = 6 ...