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是 ...
随机推荐
- Linq知识大全
select的源码public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable< ...
- javascript笔记之正则表达式
1.在js正则表达式特殊的需要转义的字符有: ^ $ . * + ? = ! : | \ / ( ) [ ] { } 但实际应用中,还要根据实际情况来判断,以上字符可能不需要转义,也可能不止以上字符 ...
- python实现雅虎拍卖后台自动回复卖家消息
前些时间,公司让做一个自动回复卖家信息的程序,现在总结下(用python实现的) 1.登陆雅虎拍卖后台手动获取cookie文件 #coding=utf-8 import sqlite3 import ...
- JFreeChart入学教程
JFreeChart入学教程 2011-08-08 14:55:19| 分类: 技术篇 |举报 |字号 订阅 JFreeChart 是一组功能强大.灵活易用的Java绘图API,使用它可以生成多 ...
- python调用Moxa PCOMM Lite通过串口Ymodem协议发送文件
本文采用python 2.7编写. 经过长期搜寻,终于找到了Moxa PCOMM Lite.调用PCOMM.DLL可以非常方便的通过串口的Xmodem.Ymodem.Zmodem等协议传输文件,而无需 ...
- Django web 开发指南 no such table:
在学习django web开发指南时,发布新博客点击save后会有error提示:no such table balabalabala... 百度了一下说重新运行manage.py syncdb 就可 ...
- 警惕arm-linux-gcc编译器优化选项
arm-linux-gcc的优化选项例如(-O2),可以加速我们的程序,使程序执行效率更高.但是,倘若我们就是需要程序慢一点运行,但是优化却把我们的延时函数优化的没有了的时候,这种优化却不是我们想要的 ...
- Windows server2008 搭建ASP接口访问连接oracle数据库全过程记录--备用
真的是太不容易了,以前的时候在window server 2003上面搭建了一套asp+oracle的接口系统,就费了好大的劲儿,其实那会迷迷瞪瞪的也不知道怎么的就弄好了,也懒得管了.OK,从昨天到今 ...
- 发布FireBird数据库所需要DLL文件
数据库版本:2.5.2 ib_util.dll; icudt30.dll; icuin30.dll icuuc30.dll
- http://jinnianshilongnian.iteye.com/blog/2018936
http://jinnianshilongnian.iteye.com/blog/2018936