Interceptors allow you to define code to be executed before and/or after the execution of an Action method. (The "Filter" pattern.)
downpour在这里对拦截器做了很好的描述
http://struts2.group.iteye.com/group/wiki/1397-deep-into-struts2-interceptors
从下载的struts2的document中截取的一副ActionLifeCyle中可以看到拦截器的设计是一个典型的责任链模式。
定义我们自己的拦截器可以通过实现Interceptor接口或extends AbstractInterceptor抽象类
Interceptor接口
public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; }
public abstract class AbstractInterceptor implements Interceptor { public void init() { } public void destroy() { } /** * Override to handle interception */ public abstract String intercept(ActionInvocation invocation) throws Exception; }在拦截器中通过传递ActionInvocation实例,调用其invoke()方法来达到流程继续往下执行,这里我们可以直接在拦截器中返回一个resultCode,如果我们不使用invocation.invoke()来完成堆栈中下一个元素的调用,而是直接返回一个字符串作为执行结果,那么整个执行将被中止。如:
public class SecurityInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { if(LoginAction.class == invocation.getAction().getClass()) { return invocation.invoke(); } return ""; } }也可以通过invoke()方法使流程继续向下执行
public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("LoginInterceptor invocation.invoke()之前的代码....."); //invocation.invoke();之前的代码会在Action之前执行 String result = invocation.invoke(); //invocation.invoke();之后的代码会在Action之后执行 System.out.println("LoginInterceptor invocation.invoke()之后的代码....."); return result; } }如果有下一个过滤器就调用下一个过滤器,没有就通过invokeActionOnly()调用Action
//得到下一个拦截器,传递invocation参数,调用其intercept()方法, //而intercept中又调用invoke(),以此递归实现 resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
resultCode = invokeActionOnly();这是配置了PreResultListener的调用代码:
listener.beforeResult(this, resultCode);最后执行Result:
// now execute the result, if we're supposed to if (proxy.getExecuteResult()) { executeResult(); }在配置拦截器的时候还可以指定<param>参数(使用部分的参数配置会覆盖定义部分的参数配置