拦截器
【导读】
action就是一个动作,就好比如,我们要去做某件事情的之前,脑海里首先会去想该如何去做,层层分析.例如我们要去大海游泳,去之前,我们得想好,今天天气怎么样,适不适合去海...等条件,如果条件成立了,即通过了,那么我们就可以去海游泳了,但是,天气下雨了,我们就会把去大海游泳整件事情终止了..动作将不会去执行,而动作之前的这些想法,可以理解成我们的拦截器、
我们可以看看一张Action LifeCycle的图
在图中我们可以发现,除了action,其他的都是interceptor(拦截器),Struts2的Interceptor一层一层,把Action包裹在最里面,整个结构就好比,我们在游戏的时候,action就是一个BOSS,要打BOSS之前得通过层层关卡...方能找到。
在执行Action的代码之前或之后,拦截器会打断Action的执行,让程序先执行拦截器的代码,这也许就是为什么把它叫做拦截器
的原因。有的时候,拦截器还会阻止Action的执行,比如说在验证失败的情况下,应该让程序返回到输入界面让用户重新输入。
每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:
1) 中止整个执行,直接返回一个字符串作为resultCode
2) 通过递归调用负责调用堆栈中下一个Interceptor的执行
3) 如果在堆栈内已经不存在任何的Interceptor,调用Action
【代码】
Interceptor的定义
我们来看一下Interceptor的接口的定义:
1 public interface Interceptor extends Serializable { 2 3 /** 4 * Called to let an interceptor clean up any resources it has allocated. 5 */ 6 void destroy(); 7 8 /** 9 * Called after an interceptor is created, but before any requests are processed using 10 * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving 11 * the Interceptor a chance to initialize any needed resources. 12 */ 13 void init(); 14 15 /** 16 * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the 17 * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code. 18 * 19 * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself. 20 * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}. 21 */ 22 String intercept(ActionInvocation invocation) throws Exception; 23 }
在以上代码中,我们很显然的可以看出Interceptor接口定义,有init和destroy方法,以及intercept方法,intercept方法所依赖的参数是ActionInvocation,中文字面意思是action的调用者。
我们再来看看一个典型的Interceptor的抽象实现类:
1 public abstract class AroundInterceptor extends AbstractInterceptor { 2 3 /* (non-Javadoc) 4 * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation) 5 */ 6 @Override 7 public String intercept(ActionInvocation invocation) throws Exception { 8 String result = null; 9 10 before(invocation); 11 // 调用下一个拦截器,如果拦截器不存在,则执行Action 12 result = invocation.invoke(); 13 after(invocation, result); 14 15 return result; 16 } 17 18 public abstract void before(ActionInvocation invocation) throws Exception; 19 20 public abstract void after(ActionInvocation invocation, String resultCode) throws Exception; 21 22 }
在上面代码中,我们可以看出,
1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。
2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。
如果我们不使用invocation.invoke()方法来完成下一个元素的调用,而是直接返回一个字符串为执行结果,那么,整个执行就会终止.
【自己动手,丰衣足食】
明白了原理之后还需要做几项具体的工作:
1,自己写一个拦截器,实现检查用户是否登陆的功能。
2,添加拦截器的配置,让我们自己写的拦截器起作用。
先在src下建立一个包:com.interceptor
在这个包下建立一个类LogonInterceptor继承于AbstractInterceptor,覆盖intercept()方法:
即将上课,晚上回去再补上