值栈背后的故事

来源:互联网 发布:手机移动网络dns被劫持 编辑:程序博客网 时间:2024/06/05 15:42

为什么可以直接使用表达式来获取值呢,它是怎么工作的。

 

当请求刚过来的时候,刚开始经过的是拦截器,在这里初始化并且创建对象栈,

拦截器又有两个,经过ModelDriven的时候把model对象放进对象栈的栈顶。原来栈顶的话是action(可以通过<s:debug>标签查看),现在就是model

struts2自动把action对象放入值栈中

放入的时间点是strut2调用actionaction方法的时候,但是在调用这个方法之前,先创建了一个叫strutsActionProxy对象,然后在初始化的时候在创建并且把action对象放入值栈中。

在经过params的时候,Params拦截器的作用:封装参数。

如何封装?第一,先到对象栈中封装;第二,再到Map中封装;

 

在处理完上述工作后,当调用完所有的拦截器后,最后会调用Action类的Action方法,在调用Action方法之前,会将ValueStack对象顶层节点中的属性值赋给Action类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在Struts 2调用拦截器的过程中,可以改变ValueStack对象中属性的值,当改变某个属性值后,Action类的相应属性值就会变成在拦截器中最后改变该属性 的这个值。

 

例子:假如,现在对象栈中有model对象在(含有idname属性)在栈顶,action对象(含有idage属性);页面访问地址:xx.action?id=3&name=ab&age=20&xx=00;

   经过Params拦截器时,它如何将参数封装?

——先从栈顶开始找,依次找到idnameage属性,通过各自的Set方法依次设值id=1,name=a,age=11,但是对象栈中没有xx属性,于是栈中就没有这个参数了,通过对象栈就无法得到xx参数,但是Map中有parameters,可以把所有参数放入parameters中,无论在对象栈中有没有写属性,在parameters中都能得到;

利用表达式获取的request对象和当前request对象是不是一样的呢。

通过c:debug标签我们可以获取到这个request对象

这个对象是org.apache.struts2.dispacher.StrutsRequestWrapper@6cee5

因为重写了getAttribute方法,所以EL也可以使用这个值栈的原理             如果key为空,那么会抛出一个异常,然后从ActionContext中获取数据,还是为空的话,创建了一个ValueStack对象,如果不为空,则表示找到了值。同时:action中属性的默认值是空

 

在使用s:proprety标签的时候,获取的是值栈中对象的属性值,[0]代表栈顶,也可以忽略不写

在获取Map栈内容的时候,获取requestsession,等对象的内容的时候,需要利用#加上session,等来获取

希望这篇文章对大家有所帮助。

 


原创粉丝点击