Struts2的ValueStack(值栈)介绍

1.在之前写的一些文章中,有用到<s:debug></s:debug>这个Struts2自带的标签,会在jsp页面中产生一个Debug按钮,点击这个按钮时,就会出现ValueStack(值栈)和Stack Context(栈的上下文环境)的内容,今天就来介绍一下ValueStack(值栈)。



2.ValueStack对象相当于一个栈,它贯穿整个Action的生命周期,每个Action类的对象实例都会拥有一个ValueStack对象。

(1).当Struts2接收到一个*.action请求后,并不是直接调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点。

值栈也位于内存当中,它也是和parameters,request,session,application,attr对象放在一起的。

值栈属于OGNL Context里面的根对象,即值栈位于整个内存当中最为重要的地方,所以叫根对象。

(1).其中根对象和另外五个对象(parameters,request,session,application,attr)是有区别的,根对象在获得属性值时可以省略#号,比如<s:property value="user.username"/>,而那另外5个对象就要加上#号了,根对象是放在值栈内容中的,另外5个对象是放在值栈上下文环境中的,要使用#key.属性名取得。

(2).值栈的生命周期与request请求有关,每次请求产生一个值栈。默认所有的Action会被自动放到值栈里面去。



3.在服务器跳转时是共有值栈的,假设从一个Action1通过服务器跳转到Action2的话,就意味着这两个Action是共享一个值栈的,因为一次请求只使用一个值栈。这时内存中情况是这样的,首先,接收到Action1请求后,会产生一个值栈,在栈顶存放Action1对象以及它的所有属性。然后经过服务器跳转到Action2,这时会把Action2对象压入值栈的栈顶位置,此时Action1对象以及Action1的所有属性就位于栈底了。

(1).当请求过程是通过服务器跳转的话,它的取值过程是怎样的呢?

栈的特征是后进先出。于是首先到栈顶的对象里查找是否存在这个属性,如果栈顶的Action2对象中不存在这个属性的话,它会继续向下寻找直至栈底对象,一直查找是否存在这个属性,如果最后找到该属性的话,那么就会在JSP页面中通过<s:property value="属性名"/>输出属性值,如果在Action1和Action2都有一个同名的同类型的属性的话,那么将输出Action2中的属性值,因为它是先从栈顶开始寻找属性的,值栈的特征是后进先出,Action2对象及其它对应的属性是后进的,所以先出,就先取得Action2中的属性。

(2).其中有三种语法可以获得Action类中的属性:

首先,设此时想获取Action1中的username属性的话,可以使用值栈的Top语法或者N语法。

使用Top语法获取值栈中的第二个对象的属性:<s:property value="[1].top.username"/>

使用N语法获取值栈中第二个对象的属性:<s:property value="[1].username"/>

另外值栈还有一个@语法,例如@语法调用Action中的静态方法:<s:property value="@vs@getVOMethod()"/>

@vs@get()等价于@vs1@getVOMethod(),指的是栈顶对象的静态getVOMethod()方法,同理,@vs2@getVOMethod()就是取值栈中第二个对象的静态getVOMethod()方法。



4.在客户端跳转时使用各自的值栈,不是像服务器跳转时一样是共享值栈了,假如中间某一步骤中出现了客户端跳转的话,那么两个Action所使用的就是两个不同的值栈了,所以在Action2中就不能再使用Action1中的属性了,在最后跳转的JSP页面中也就无法获取Action1的属性了。

即Action2跳转到JSP页面时使用的是redirect重定向的类型的话,那么最后值栈是没有任何Action对象的。这个时候我们可以通过链接传参,如<result type="redirect">/user_success.jsp?t=${type}</result>,意思就是取出Action2的type属性作为参数,通过浏览器地址栏传递到JSP页面中,然后使用OGNL表达式中的#号获取parameters对象的属性,即::<s:property value="#parameters.t"/>就可以取到值了。这个有点类似我之前写过的向结果集传参的一篇文章,大家可以参考下,文章地址:http://blog.csdn.net/u012561176/article/details/44803435 。



5.我们也可以手工的向值栈压入对象,正常情况下值栈保存的是Action对象,而我们也可以直接往值栈中添加其他对象,这时可以在Action类中添加如下代码:

ActionContext.getContext.getValueStack().push(new Person("林业雄",23));

向值栈中添加对象,即把这个对象压入栈中,我们手工往值栈里添加的Person对象会存放在栈顶当中。

这时Struts2会初始化这个Action,把Action对象放到值栈里面去了,然后调用执行Action类的execute()方法是,就会往值栈中添加了Person对象。


6.以上内容仅供大家学习参考,如有雷同,纯属巧合,我也是根据老师的文档所写的,在我之前的文章里面也有涉及到ValueStack(值栈)里的东西,大家可以去看下,谢谢!


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值