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是 ...
随机推荐
- 读取xml文件(可执行文件根目录debug)
xml文件格式如下 <?xml version="1.0" encoding="utf-8" ?> <root> <appKey& ...
- SVG
目前SVG在国内的使用并不常见,并且关于svg的相关js库也不多,这里指出两款svg的库Snap.svg和svg.js,Snap.svg张鑫旭的博客上有关于他的使用APi http://www.zha ...
- PHP、JSP、.NET各自的真正优势是什么
PHP的优势在于, 跨平台, 极易部署, 易维护, 为Web而生, 开源社区强大, 文档丰富.至于说3足鼎立, 谈不上, 全球前100万的sites中, 70%是PHP. JSP和Asp..net 也 ...
- 如何得到django中form表单里的复选框(多选框)的值( MultipleChoiceField )
直接写代码吧 CHECKBOX_CHOICES = ( ('Value1','Value1'), ('Value2','Value2'), ) class EditProfileForm(ModelF ...
- C++ 11 笔记 (四) : std::bind
std::bind 接受一个可调用的对象,一般就是函数呗.. 还是先上代码: void func(int x, int y, int z) { std::cout << "hel ...
- 《疯狂java讲义》笔记 1-5章
1.编译语言和解释语言理解,摘自李刚老师的<疯狂Java讲义>第三版: 就是说,Java和.net都是编译型有事解释型语言.编译型就是根据不同平台编译成不同的可执行机器码,编译过程中会进行 ...
- NET Portability Analyzer
NET Portability Analyzer 分析迁移dotnet core 大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易 ...
- 【原】jQuery编写插件
分享一下编写设置和获取颜色的插件,首先我将插件的名字命名为jquery.color.js.该插件用来实现以下两个功能1.设置元素的颜色.2.获取元素的颜色. 先在搭建好如下编写插件的框架: ;(fun ...
- 【产品体验】喵街&飞凡
最近O2O很火啊,我也来找几个O2O产品体验下~~~ 阿里今年5月30号上线了一款线下逛街App——喵街,号称消费者的逛街神器.阿里去年已经与银泰合作一年,探索互联网和传统实体零售合作之路,这次则免费 ...
- hdu 4433
一道dp题,虽然知道是dp,但是不会做: 学习了ACM_cxlove大神的代码,终于明白了: 搬运工: dp[i][j][k]表示 前i个已经完全匹配,而这时候,第i+1个已经加了j位,第i+2位已经 ...