在struts的开发文档有一个图,从这个官方的picture,你也能大致的看出struts到底是怎么样执行的。
说明:一个请求(HttpServletRequest)到来,它会经过FilterDispatcher(这个原来的,现在已经的是StrutsPrepareAndExecuteFilter)。当HttpServletRequest到达FilterDispatcher的时候,FilterDispatcher会帮我们创建ActionPproxy,ActionProxy通过ConfigurationManager从struts.xml配置文件中读出来相应的配置信息。ActionProxy拥有一个AcionInvocation的实例,接下来,它会调用ActionInvocation的invoke方法,在invoke方法里面,它会先调用第一个interceptor1,然后再调用第二个interceptor2,再调用第三个interceptor3,最后再调用action,action会返回一个result,根据result找到相应的视图(jsp,FreeMarker等)。然后再经过interceptor3,interceptor2,interceptor1,FilterDispatcher将用户请求的信息反馈给用户。
下面我们就来模拟Struts2的拦截器
工程目录结构以及文件如下:
1.ActionInvocation.java里面有action的引用和很多interceptor
import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ActionInvocation { protected Object action;// action的引用 protected Iterator<Interceptor> interceptors; protected String resultCode;// 保存action执行的result ActionInvocation() { action = new Action(); List<Interceptor> interceptorList = new ArrayList<Interceptor>(); interceptorList.add(new FirstInterceptor()); interceptorList.add(new SecondInterceptor()); interceptors = interceptorList.iterator(); } public String invoke() { if (interceptors.hasNext()) {// 是否还有下一个interceptor resultCode = this.interceptors.next().intercept( ActionInvocation.this); } else {// 说明所有的interceptor都调用完了,通过反射调用Action中的方法 resultCode = this.invokeActionOnly(); } return resultCode; } public String invokeActionOnly() { Action ac = (Action) action; return ac.execute(); } }
2.所有的拦截器都实现的interceptor接口
public interface Interceptor { public String intercept(ActionInvocation actionInvocation); }
3.生成2个拦截器FirstInterceptor,SecondInterceptor,都实现了Interceptor接口
FirstInterceptor
public class FirstInterceptor implements Interceptor{ @Override public String intercept(ActionInvocation invocation) { String result; System.out.println(1); result = invocation.invoke(); System.out.println(-1); return result; } }
SecondInterceptor
public class SecondInterceptor implements Interceptor{ @Override public String intercept(ActionInvocation invocation) { String result; System.out.println(2); result = invocation.invoke(); System.out.println(-2); return result; } }
3.编写Action
public class Action { public String execute(){ System.out.println("------execute----------"); return "success"; } }
4.编写测试类
public class Test { public static void main(String[] args) { new ActionInvocation().invoke(); } }