拦截器

【导读】

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()方法:

即将上课,晚上回去再补上

 

 

 

 posted on 2012-05-24 13:08  蔡傑儒  阅读(270)  评论(0编辑  收藏  举报