简答的说,Interceptor(拦截器)将Action共同的行为独立出来,分散了关注编程的方法。
在下面实例中,你将看到Interceptor如何在Action执行的前后运行,以及怎么样把结果返回给用户。下图将对你理解有帮助。
当一个请求到达struts2框架时,将顺序执行一下的行为。
1. Struts2框架首先找到处理这个请求的Action,并发现我这个Action相关联的拦截器。
2. 框架将创建一个ActionInvocation的实例,并且调用它的invoke()方法。此时框架的控制权转交给ActionInvocation。
3. Action和Interceptor在框架中执行是由ActionInvocation对象调用的,ActionInvocation知道哪一些拦截器将会被调用。
4.ActionInvocation现在调用堆栈中第一个拦截器的intercept()方法。
看下面这个例子,它只有一个拦截器来记录日志的信息。
LoggingInterceptor代码如下:
- public String intercept(ActionInvocation invocation) throws Exception{
- //Pre processing
- logMessage(invocation, START_MESSAGE);
- String result = invocation.invoke();
- //Post processing
- logMessage(invocation, FINISH_MESSAGE);
- return result;
- }
调用,然后ActionInvocation将依次调用堆栈中的拦截器直达最后一个为止。
2.执行完所有的拦截器之后,Action将会被调用,最后返回一个结果字段相应的视图将会被呈现。这是正常的事件流。
3.但是如果出现验证错误,请求处理将会被停止。没有进一步的拦截器将会被调用,Action将不会被执行。控制流变化了,为了处理请求并呈现一个视图给用户拦截器将会被逆向的调用
4.回到例子,logger拦截器仅仅在堆栈里拦截,所以在记录下“START_MESSAGE”后,ActionInvocation的invoke()方法将会调用Action。我们的Action仅仅返回一个“success”,然后logger拦截器将会被调用做后期处理,这是“FINISH_MESSAGE”被记录并返回结果。根据这个结果相应的视图将会被呈现给用户。
拦截器使用的好处:
1、非常灵活。
2、清洁,让我们只集中在Action的编写上。
3、增强了代码的可读性和可重用性。
4、测试过程更加容易
5、我们只需要添加我们需要的拦截器到堆栈里并且为每个请求定制相应的Action处理。
现在看这个测试类:
- package com.zcl.struts.interceptor;
- public class TestLoggerAction {
- public String execute(){
- System.out.println("Inside Action") ;
- return "success" ;
- }
- }
- <package name="interceptor" extends="struts-default">
- <action name="LoggerAction" class="com.zcl.struts.interceptor.TestLoggerAction">
- <interceptor-ref name="logger" />
- <result>/success.jsp</result>
- </action>
- </package>
在配置里面,interceptor-ref是为Action增加一个logger的拦截器引用。所有的拦截器被定义在 struts-default.xml文件的struts-default里。
我们还需要一个index.jsp。
- <META HTTP-EQUIV="Refresh" CONTENT="0;URL=LoggerAction.action">
在地址栏输入http://localhost:8888/struts页面跳转到success.jsp,将会在控制台看到一系列信息。
- 2011-12-23 9:59:23 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
- 信息: Starting execution stack for action //TestLogger
- Inside Action
- 2011-12-23 9:59:23 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
- 信息: Finishing execution stack for action //TestLogger