总控制器:ActionInvocation:

struts通过ActionInvocation来递归调用拦截器入口是DefaultActionInvocation的invoke()方法:

 if (interceptors.hasNext()) {//如果还有拦截器
                final InterceptorMapping interceptor = interceptors.next();//next获取下一个拦截器
                String interceptorMsg = "interceptor: " + interceptor.getName();
                UtilTimerStack.push(interceptorMsg);
                try {            //把DefaultActionInvaction作为参数调用intercept方法把控制权交给拦截器
                                   // 并且继续调用DefaultA...的invoke()方法直到最后一个拦截器
                                resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);
                            }
                finally {
                    UtilTimerStack.pop(interceptorMsg);
                }
            } else {
                resultCode = invokeActionOnly();//最后一个拦截器
            }

1、params拦截器

把数据转移到ValueStack上发现的第一个匹配的属性上

2、static-params拦截器:

这个拦截器也是将参数转移到ValueStack上公开的属性上去,不同的是这个拦截器转移的参数定义

在框架声明性动作元素中,如在xml中声明的元素,并且static-params拦截器在params拦截器之前

所以有可能这个拦截器转移的参数会被后一个给覆盖

3、ServletConfigInterceptor拦截器:将servlet api 注入到action中去,如果一个动作想要获取一个比如HttpServletRequest对象,可以继承ServletRequestAware接口,在这个接口中定义了一个方法

public void setServletRequest(HttpServletRequest request);

用来注入request对象。

public String intercept(ActionInvocation invocation) throws Exception {
        final Object action = invocation.getAction();
        final ActionContext context = invocation.getInvocationContext();

        if (action instanceof ServletRequestAware) {
            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
            ((ServletRequestAware) action).setServletRequest(request);
        }

        if (action instanceof ServletResponseAware) {
            HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE);
            ((ServletResponseAware) action).setServletResponse(response);
        }

        if (action instanceof ParameterAware) {
            ((ParameterAware) action).setParameters((Map)context.getParameters());
        }

        if (action instanceof ApplicationAware) {
            ((ApplicationAware) action).setApplication(context.getApplication());
        }
        
        if (action instanceof SessionAware) {
            ((SessionAware) action).setSession(context.getSession());
        }
        
        if (action instanceof RequestAware) {
            ((RequestAware) action).setRequest((Map) context.get("request"));
        }

        if (action instanceof PrincipalAware) {
            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
            if(request != null) {
                // We are in servtlet environment, so principal information resides in HttpServletRequest
                ((PrincipalAware) action).setPrincipalProxy(new ServletPrincipalProxy(request));
            }
        }
        if (action instanceof ServletContextAware) {
            ServletContext servletContext = (ServletContext) context.get(SERVLET_CONTEXT);
            ((ServletContextAware) action).setServletContext(servletContext);
        }
        return invocation.invoke();
    }

4、DefaultWorkflowInterceptor提供数据验证及验证错误发生时改变后续工作流

5、prepare拦截器

prepare拦截器会在action上查找该动作是否继承了preparable接口,如果继承了,则会调用

相应的prepare()方法。

方法命名规则:input()方法:prepareInput()或者prepareDoInput()

6、modelDriven拦截器:

 public String intercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

        if (action instanceof ModelDriven) {
            ModelDriven modelDriven = (ModelDriven) action;
            ValueStack stack = invocation.getStack();
            Object model = modelDriven.getModel();
            if (model !=  null) {//这就是为什么要在action中实例化model
                stack.push(model);//将模型放到栈顶
            }
            if (refreshModelBeforeResult) {
                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));
            }
        }
        return invocation.invoke();