在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();
}
}