一、什么是值栈?
==> Struts2是在有请求到达的时候为每个请求创建一个新的值栈,也就是说值栈和请求是一一对应的,值栈封装了一次请求所需要的所有数据。因此,Strus2引入值栈最主要的目的,就是在页面与Action之间进行数据交换。
其作用:用于在前台-后台之间传递数据,最典型的做法就是将Struts2标签与OGNL表达式的结合,ValueStack(值栈)实际上是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是OGNL的基础。
值栈封装了一次请求所需要的所有相关数据,要获取值栈中存储的数据,首先应该获取值栈。
因此,这种一一对应的关系使值栈能够线程安全的为每个请求提供公共的数据存取服务。
ValueStack的生命周期是随着request的创建而创建,随request的销毁而销毁。
ValueStack贯穿整个 Action 的生命周期,每个Action 类的对象实例都拥有一个ValueStack对象, 在其中保存当前Action 对象和其他相关对象。Struts2框架把ValueStack 对象保存在名为 “struts.valueStack” 的request属性中,也就是说ValueStack与Action的生命周期保持一致。
二、如何获取值栈
方法一:在request中获取值栈
request.setAttribute(“struts.valueStack”,valuestack对象);
方法二:在ActionContext中获取值栈
ValueStack valueStack = ActionContext.getContext().getValueStack();
三、值栈内部组成
ObjectStack
(对象栈):是CompoundRoot类型,用ArrayList定义,Struts2把动作和相关对象压入ObjectStack中。
ContextMap
(Map栈):是OgnlContext类型,是个Map集合,Struts2 把各种各样的映射关系(一些Map类型的对象)压入ContextMap中。
四、应用方式
- 属性驱动:每次请求访问Action的对象时,Action中的属性对象会被自动压入ValueStack中。
- 模型驱动:Action如果实现了ModelDriven接口,那么ModelDrivenInterceptor拦截器会生效,会将model对象压入到valueStack中。
在Struts2中,同样支持使用EL表达式直接访问值栈中的数据,只需把页面取值表达式换成EL表达式即可。
五、OGNL表达式
OGNL的全称是对象图导航语言(Object-Graph Navigation Language)
是一种功能强大的开源表达式语言,可以通过某种表达式语法,存取Java对象的任意属性,调用Java对象的方法,同时能够自动实现必要的类型转换。是Struts2默认的表达式语言。
1.支持对象方法调用。
objName.methodName();
2.支持类静态方法调用和值访问,表达式的格式为@[类全名(包括包路径)]@[方法名 | 值名]。
java.lang.String@format(‘foo %s’, ‘bar’);
3.支持赋值操作和表达式串联。
例如:price=100,discount=0.8,calculatePrice(),在方法中进行乘法计算会返回80。
4.访问OGNL上下文(OGNL context)和ActionContext。
5.操作集合对象。
OGNL结构的三个要素
1.表达式
OGNL的getValue()方法中有两个参数:第一个参数是表达式。OGNL会根据表达式去对象中取值。所有OGNL操作都是针对表达式解析后进行的。
2.Root对象
OGNL的getValue()方法中的第二个参数就是Root对象,Root对象可以理解为OGNL的操作对象
3.Context对象
Root对象所在环境就是OGNL的上下文环境(Context)。上下文环境Context是一个Map类型的对象,在表达式中访问Context中的对象,需要使用“#”号加上对象名称,即“#对象名称”的形式。
OGNL的调用方式
OGNL表达式是通过“对象名.方法名()”的形式来调用对象方法表达式的
Ognl.getValue("方法名", 对象名);
作者: 肖sir@ZHBIT
2018 年 09月 27日
网友评论