欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

struts2 18拦截器详解(十)

程序员文章站 2023-08-25 23:44:23
modeldriveninterceptor      该拦截器处于defaultstack中的第九的位置,在scopedmodeldriveninterceptor拦...
modeldriveninterceptor

 

   该拦截器处于defaultstack中的第九的位置,在scopedmodeldriveninterceptor拦截器之后,要使该拦截器有效的话,action必须实现modeldriven接口,该接口就一个方法:getmodel(),modeldriveninterceptor拦截器主要做的事就是调用action的getmodel()方法然后把返回的model压入值栈(如果不为null)。如果action实现了scopedmodeldriven接口也就实现了modeldriven接口,因为scopedmodeldriveninterceptor在执行的过程肯定会返回一个model对象再调用action的setmodel(model)方法,如果action对model进行了接收,那么在执行到modeldriveninterceptor拦截器的时候,action的getmodel()方法返回的就是scopedmodeldriveninterceptor拦截器设置进去的值,已经不为null了,所以该model自然就会压入值栈。下面是该拦截器intercept方法:

[java]  

@override  

public string intercept(actioninvocation invocation) throws exception {  

    object action = invocation.getaction();//获取当前正在执行的action  

    //如果action实现了modeldriven接口  

    if (action instanceof modeldriven) {  

        modeldriven modeldriven = (modeldriven) action;  

        valuestack stack = invocation.getstack();  

        object model = modeldriven.getmodel();//通过getmodel方法获取model  

        if (model !=  null) {//如果model不为null则把model压入值栈  

            stack.push(model);  

        }  

        if (refreshmodelbeforeresult) {//在执行result之前是否要更新model对象,默认为false  

            invocation.addpreresultlistener(new refreshmodelbeforeresult(modeldriven, model));  

        }  

    }  

    return invocation.invoke();//调用下一个拦截器  

}  

 

   该方法逻辑很简单,正如前所说的一样,就是把getmodel方法返回的结果压入值栈而已,我们一般实现这个接口是利用压入值栈的model对象接收从页面提交过来的数据,有很多时候我们是在action中写属性来接收参数的,因为action也是在值栈中,而struts2在赋值参数的时候是在值栈从栈顶往栈底寻找有相应setter方法的对象,而这时model压入了值栈,它是处于栈顶的,所以从页面提交过来的参数也就被model对象接收了。这种方式呢model对象有点像struts1.x里面formbean对象的功能。

 

   modeldriveninterceptor拦截器中还有个名为refreshmodelbeforeresult的属性,用于设置在执行result之前是否要更新model对象,默认值是false也就不会去更新,我们有可能在action的执行过程将model这个引用变量指向了另外一个对象,如果你把refreshmodelbeforeresult设置了为true,那么在result执行之前preresultlistener就会用这个新的对象将值栈中的对象替换,达到更新效果。

 

   preresultlistener是一种监听器由actioninvocation对象进行注册,在result执行之前会执行该种监听器的beforeresult方法。虽然在defaultstack中,struts2是不会在actioninvocation中注册这个refreshmodelbeforeresult监听器的,我们还是去简单看一下:

[java]  

protected static class refreshmodelbeforeresult implements preresultlistener {  

    private object originalmodel = null;  

    protected modeldriven action;  

  

  

    public refreshmodelbeforeresult(modeldriven action, object model) {  

        this.originalmodel = model;  

        this.action = action;  

    }  

  

    public void beforeresult(actioninvocation invocation, string resultcode) {  

        valuestack stack = invocation.getstack();//获取值栈  

        compoundroot root = stack.getroot();//获取值栈的root对象  

  

        boolean needsrefresh = true;  

        object newmodel = action.getmodel();//从action中获取新的model对象  

  

        // check to see if the new model instance is already on the stack  

        for (object item : root) {  

            if (item.equals(newmodel)) {//如果新的model对象与旧的相同则不刷新  

                needsrefresh = false;  

            }  

        }  

  

        // add the new model on the stack  

        if (needsrefresh) {//如果要刷新  

  

            // clear off the old model instance  

            if (originalmodel != null) {  

                root.remove(originalmodel);//先移除旧model  

            }  

            if (newmodel != null) {  

                stack.push(newmodel);//将新model对象压入值栈  

            }  

        }  

    }  

}  

 

   refreshmodelbeforeresult实现了preresultlistener接口,是modeldriveninterceptor的一个静态内部类,在执行result之前执行其beforeresult方法

如何进行刷新的很简单相信大家都看得懂。