拦截器的整个过程

程序是在执行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 拦截器的更多相关文章

  1. Struct2 自定义拦截器

    1 因为struct2 如文件上传,数据验证等功能都是由系统默认的 defalutStack中的拦截器实现的,所以我们定义拦截器需要引用系统默认的defalutStack 这样才不会影响struct2 ...

  2. Spring Aop、拦截器、过滤器的区别

    Filter过滤器:拦截web访问url地址.Interceptor拦截器:拦截以 .action结尾的url,拦截Action的访问.Spring AOP拦截器:只能拦截Spring管理Bean的访 ...

  3. Struts2 (四) — 拦截器

    一.拦截器 1.概述 1.1什么是拦截器 ​ 在struts2中,拦截器(Interceptor)是用来动态拦截Action执行的对象. ​ 拦截器有点类似以前Servlet阶段的Filter(过滤器 ...

  4. 6. ModelDriven拦截器、Preparable 拦截器

    1. 问题 Struts2 的 Action 我们将它定义为一个控制器,但是由于在 Action 中也可以来编写一些业务逻辑,也有人会在 Action 输入业务逻辑层. 但是在企业开发中,我们一般会将 ...

  5. springmvc的拦截器

    什么是拦截器                                                         java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...

  6. Struts的拦截器

    Struts的拦截器 1.什么是拦截器 Struts的拦截器和Servlet过滤器类似,在执行Action的execute方法之前,Struts会首先执行Struts.xml中引用的拦截器,在执行完所 ...

  7. Struts2拦截器的执行过程浅析

    在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...

  8. 学习SpringMVC——拦截器

    拦截器,顾名思义就是用来拦截的. 那什么是拦截,又为什么要拦截.对于Spring MVC来说,拦截器主要的工作对象就是用户的请求,拦截下来之后,我们可以在拦截的各个阶段悉心呵护[为所欲为].常见的比如 ...

  9. alias拦截器的使用

    在SSH项目中,有时需要由一个Action跳转到另一个Action.有两种方式可以实现Action之间的跳转,一种是chain,另一种是redirectAction,这两种方式之间的区别是chain是 ...

随机推荐

  1. 结构型模式(Structural patterns)->外观模式(Facade Pattern)

    动机(Motivate): 在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化.那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子 ...

  2. [python]filter

  3. zzuli oj 1145 有问题的里程表 2

    Description 某辆汽车有一个里程表,该里程表可以显示一个整数,为该车走过的公里数.然而这个里程表有个毛病:它总是从3变到5,而跳过数字4,里程表所有位(个位. 十位.百位等)上的数字都是如此 ...

  4. 隐私:网民最常用密码MD5解密

    国内知名网络安全商瑞星公司曾发布过一项针对密码强度的专业研究报告,这项研究中列举了中国网民和美国网民最常用的密码集.研究表明,全球互联网大部分用户在密码使用中都存在着种种疏漏,一些极其简单的密码被广泛 ...

  5. APNs-远程推送

    一.开发iOS程序的推送功能, iOS端需要做的事 1.请求苹果获得deviceToken 2.得到苹果返回的deviceToken 3.发送deviceToken给公司的服务器 4.监听用户对通知的 ...

  6. JDK神坑:JAVA中Calendar的月份Month少1

    很多朋友在使初次使用Calendar时,会发现月份莫名其妙对不上,显示的结果总是比预期中小1个月,检查好几遍也没发现程序有错,于是开始抓狂.其实这个时候,只要去看JDK就会明白问题所在.JDK告诉我们 ...

  7. 个人笔记--struts2对Action的权限拦截

    一.编写一个类实现com.opensymphony.xwork2.interceptor.Interceptor 接口 PermissionInterceptor.java <pre name= ...

  8. python之--输入输出

    python之输出 用print加上字符串,就可以向屏幕上输出指定的文字.用代码实现如下: >>> print "i love baby!" i love bab ...

  9. spoj VFMUL FFT快速傅立叶变换模板题

    题意:求两个数相乘. 第一次写非递归的fft,因为一个数组开小了调了两天TAT. #include<iostream> #include<cstring> #include&l ...

  10. 使用SparseArray代替HashMap

    HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果.最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performanc ...