May
06


2008-05-06 4:04 pm 作者:firepig

Struts2的拦截器是基于AOP思想的,采取可配置的方式控制(可插销式)。 拦截器的使用解耦了对servlet的依赖,不在依赖Servlet API。而Struts1.x Action中的execut中有HttpServletRequest和HttpSerletResponse方法。对于Struts2的Action来说其实就是一个POJO。。。

话题回到拦截器,Strut.xml中可以定义拦截器,也可以定义一个拦截器栈,格式是:

配置好之后就可以在具体的Action引用改拦截器,引用的格式是 在定义和引用的时候都可以配置默认的参数 value 值得注意的是如果在定义和引用的时候都配置了相同的参数,那么Action中的引用参数将会覆盖默认的配置。 还有一个要注意的地方是,如果Action中指定了自己要用的拦截器,那么就必须显示的指定默认的拦截器。 有的拦截器是每个Action都要用到的,那么一个个去配置的话,就显得太麻烦了,也不符合软件复用这个指导思想。这个时候可以配置包下默认拦截器,既可以是拦截器也可以是拦截器栈, 也可以在配置参数param。这样的话这些拦截器就应用到了包中的每一个Action。虽然Struts2中的拦截器基本是帮我们完成了70%的拦截任务,但是我们很多的时候还是要自己写一个拦截器的。

怎么写一个拦截器呢,庆幸的是在struts2中这是一件简单而且愉快的事情。

首先要实现com.opensymphony.xwork2.interceptor.Interceptor接口。

public Interface Interceptor extends Serializable {

//销毁该拦截器之前的回调方法

void destory();

//初始化该拦截器的回掉方法(主要是打开一些资源)

void init();

// 拦截器实现拦截的逻辑方法

String intercept(ActionInvocation invocation) throws Exception;

}

intercept这个方法是我们需要实现的拦截动作。就像Action的execute一样,intercept方法会返回一个字符串的逻辑视图。ActionInvocation参数包含了被拦截的Action的应用,调用invoke方法,将控制权交给下一个拦截器,或者转个Action的execute方法。

跟java的API一样,大家都知道很多时候一个接口对应的会有一个抽象类实现这个接口,然后在抽象类提供接口一些方法的空实现,这样在我们在用的时候,就可以直接继承那个abstract的类,不用在实现那些我们不要的方法。 那么Struts2也提供了这样的一个方法AstractIntercepor类,这个类对init()和destory()方法进行了空实现,以为并不是我们每次实现拦截器的时候都要申请资源。ActionInvocation可以做的事情很多,我复制一段API

Method Summary
void addPreResultListener(PreResultListener listener)
Register a com.opensymphony.xwork2.interceptor.PreResultListener to be notified after the Action is executed and before the Result is executed.
Object getAction()
Get the Action associated with this ActionInvocation
ActionContext getInvocationContext()
Gets the ActionContext associated with this ActionInvocation.
ActionProxy getProxy()
Get the ActionProxy holding this ActionInvocation
Result getResult()
If the ActionInvocation has been executed before and the Result is an instance of ActionChainResult, this method will walk down the chain of ActionChainResults until it finds a non-chain result, which will be returned.
String getResultCode()
Gets the result code returned from this ActionInvocation
ValueStack getStack()

String invoke()
Invokes the next step in processing this ActionInvocation.
String invokeActionOnly()
Invokes only the action (not interceptors or results).
boolean isExecuted()

void setActionEventListener(ActionEventListener listener)
Sets the action event listener to respond to key action events
void setResultCode(String resultCode)
Sets the result code, possibly overriding the one returned by the action.

可见这个参数可以获得Action的几乎所以控制权,那你就可以做一些自己要做的事了。定义好拦截器,使用的方法就和Struts2中已经定义好的那些拦截器一样了。可以看出其实拦截器没那么神秘,也就是一个普通的类。

有的时候,我并不是想拦截Action中的所以的方法,那这个时候可以继承MethodFiledIntercepor抽象类。这个类重新了AbstractInterceptor类中的intercept方法,但是提供了doIntercept(ActionInvocation invocation)的抽象方法。从这种设计方式看,MethodFilterInterceptor类的intercept已经对Action的拦截行为进行逻辑上的过滤。多少真正的过滤还需要我们自己开发实现。 那么为什么它可以实现过滤了,我打开源文件看了一下,神秘面纱被掀开了,原来这个类有这两个方法:public void setExcludeMethods(Stirng excludeMethods); public void setIncludeMethods(Sting includeMethods); 那么就可以在引用改拦截器的时候配置这两个参数了。

另外还可以设置拦截器结果的监听器,PreResultListener实现这个接口。然后在拦截器类中手动的注册 ivocation.getPreResultListener(new OurPreResultLister());为什么不在拦截器类中的itercept中直接实现监听呢?因为这样的话看上去结构不是很清晰,可见struts2也是下足了功夫啊。 配置的话和普通的拦截器一样的配置。

最好总结一下拦截器的执行顺序。一开始我以为是按照配置的顺序执行的。其实不是。配置在前面的拦截器,在拦截方法之前的拦截动作,将会先对用户的请求起作用。如果是被拦截方法之后的拦截动作,则会后对用户请求作用。

总结完毕。说的好像有点混乱。。。

推荐(0)
收藏
分享至: Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 添加到饭否 QQ书签 POCO网摘 Digbuzz我挖网 

没有相关日志

  • 没有相关日志

网友评论:

  1. Cokar 说:

    呵呵,我看不懂这是什么

    [回复]

  2. 白的的的的 说:

    这是Struts 2的基石

    [回复]

  3. redcoatjk 说:

    是有点乱.
    我是用webwork的

    [回复]

发表评论


得到OpenID
使用OpenID提供商
35OpenID 35OpenID MyOpenID MyOpenID Flickr Flickr
Google Google Yahoo Yahoo! AOL AOL
Blogger Blogger LiveJournal LiveJournal Verisign Verisign
ClaimID ClaimID Technorati Technorati Vidoop Vidoop
OpenID OpenID 帮助