• Struts2 第三讲 -- Struts2的处理流程


    4.Struts2的处理流程

    以下是struts-defautl.xml中的拦截器

     建议通过这个struts-default的副本查看,更形象

     

    它实现了很多的功能,其中包括国际化,文件上传,类型转换,表单验证,都是在跳转到Action类处理之前就做好了,所有我们只需要在Action类中使用就可以了,大大方便了我们的开发

    下面通过使用eclipse的断点调试,看看拦截器的执行过程。我们分别在一下三个拦截器中设置断点,在我们的三个拦截器类中(invocation.invoke()所在函数中断点)中设置断点,然后根据流程查看拦截器执行顺序.

     

    @Override
        public String doIntercept(ActionInvocation invocation) throws Exception {
            Object action = invocation.getAction();
    
            if (action instanceof Preparable) {
                try {
                    String[] prefixes;
                    if (firstCallPrepareDo) {
                        prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};
                    } else {
                        prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};
                    }
                    PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);
                }
                catch (InvocationTargetException e) {
                    /*
                     * The invoked method threw an exception and reflection wrapped it
                     * in an InvocationTargetException.
                     * If possible re-throw the original exception so that normal
                     * exception handling will take place.
                     */
                    Throwable cause = e.getCause();
                    if (cause instanceof Exception) {
                        throw (Exception) cause;
                    } else if(cause instanceof Error) {
                        throw (Error) cause;
                    } else {
                        /*
                         * The cause is not an Exception or Error (must be Throwable) so
                         * just re-throw the wrapped exception.
                         */
                        throw e;
                    }
                }
    
                if (alwaysInvokePrepare) {
                    ((Preparable) action).prepare();
                }
            }
    
            return invocation.invoke();
        }

    可见简写成下面,容易理解

    PrepareInterceptor 
    
    @Override
        public String doIntercept(ActionInvocation invocation) throws Exception {
            
            //invoke()表示放行,跳转到Action类(在跳转到Action类之前,先将所有的拦截器先执行完成)
            //invoke()方法的返回值,返回Action类方法的返回值
            System.out.println("PrepareInterceptor的being方法");
            String value = invocation.invoke();
            System.out.println("PrepareInterceptor的end方法");
            return value
        }
    ChainingInterceptor 
    
    @Override
        public String intercept(ActionInvocation invocation) throws Exception {
            ValueStack stack = invocation.getStack();
            CompoundRoot root = stack.getRoot();
            if (shouldCopyStack(invocation, root)) {
                copyStack(invocation, root);
            }
            //invoke()表示放行,跳转到Action类(在跳转到Action类之前,先将所有的拦截器先执行完成)
            //invoke()方法的返回值,返回Action类方法的返回值
            System.out.println("ChainingInterceptorbeing的begin方法");
            String value = invocation.invoke();
            System.out.println("ChainingInterceptor的end方法");
            return value
    ParametersInterceptor
    
    @Override
        public String doIntercept(ActionInvocation invocation) throws Exception {
           
            //invoke()表示放行,跳转到Action类(在跳转到Action类之前,先将所有的拦截器先执行完成)
            //invoke()方法的返回值,返回Action类方法的返回值
            System.out.println("ParametersInterceptor的begin方法");
            String value = invocation.invoke();
            System.out.println("ParametersInterceptor的end方法");
            return value
        }
    public class HelloWorldAction extends ActionSupport{
    
        @Override
        public String execute() throws Exception {
            System.out.println("欢迎访问HelloWorldAction中的execute方法!");
            return "success";
        }
        //自定义add方法
        public String add(){
            System.out.println("欢迎访问HelloWorldAction中的add的方法!");
            return "success";
        }
    }

      这里注意:当执行每个拦截器时,调用拦截器中的invocation.invoke();方法前的内容,此时会陆续继续执行拦截器,执行拦截器的顺序是preparechainparams。那么执行完Action的方法后,即调用invocation.invoke(); 方法,会继续执行paramschainprepare拦截器中invocation.invoke();后的内容,所以我们看到顺序会是后又3,2,1.

     

    注意上面只是为了方便理解,所以简化了源码并在源码中添加输出语句,实际源码不能改变,具体可以自己打断点,看一下流程运转;

  • 相关阅读:
    js操作FCKeditor方法(转)
    CommandArgument绑定多个值
    fckeditor给文件(包括图片)及文件夹增加删除功能
    linq中批量删除方法
    .net里使用 escape 和 unescape(转)
    类型转换
    MEP中创建基于面的风口族
    布尔运算符和位运算符
    循环结构之FOR语句
    坏天气
  • 原文地址:https://www.cnblogs.com/lin-jing/p/8319609.html
Copyright © 2020-2023  润新知