Struts2【OGNL、valueStack】
1.什么是OGNL表达式?
OGNL(Object Graphic Navigation Language)是操作对象属性的开源表达式, Struts2框架使用OGNL作为默认的表达式语言。
2.为什么我们学习OGNL
在学习JSP的时候,我们已经学习过了EL表达式。EL表达式用起来也十分简单,我们在Struts2框架中也是可以使用EL表达式的,那么OGNL表达式好在哪里呢??
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。- 支持对象方法调用,如xxx.doSomeSpecial()
- 支持类静态的方法调用和值访问,表达式的格式【例如:"@@floor(10.9)"就是调用Math.floor()的方法了】
- 支持赋值操作和表达式串联【这个其实EL表达式也能做】
- 访问OGNL上下文(OGNL context)和ActionContext
- 操作集合对象【EL只能遍历集合,OGNL可以创建集合】
OGNL是Struts2的默认表达式语言,OGNL是配搭Strut2的标签使用的,我们学习了OGNL表达式,就可以更好地理解Struts2标签的运行以及Struts2内部的存储结构.
3.valueStack对象
在讲解OGNL表达式之前,我们先来看看valueStack对象,valueStack是Struts2数据存储的核心。我们首先要知道数据是怎么存的,存到哪里,然后才讲解OGNL表达式是怎么取出数据的。
valueStack也被称作值栈对象:
- 当用户访问Action,都会创建一个Action对象,ActionContext对象、valueStack对象;
- Struts2把Action对象放进valueStack对象之中;
- 将valueStack放进request域中,传入JSP页面;
- JSP页面就可以使用OGNL表达式获取值栈中的数据了!
4.获取valueStack对象
- 在Action中我们可以手动获取值栈对象,有两种方式获取:
1 //获取值栈对象的2种方式 2 private void getVs() { 3 // 获取值栈对象,方式1: 4 HttpServletRequest request = ServletActionContext.getRequest(); 5 ValueStack vs1 = (ValueStack) request.getAttribute("struts.valueStack"); 6 7 // 获取值栈对象,方式2: 8 ActionContext ac = ActionContext.getContext(); 9 ValueStack vs2 = ac.getValueStack(); 10 11 System.out.println(vs1 == vs2);//true 12 }
5.valueStack内部存储结构
上面已经说了,用户访问Action时,会创建Action对象,valueStack对象。Struts2内部会将Action对象存到valueStack对象之中,那么valueStack的存储结构是什么样的呢??
(1)CompoundRoot
Action对象和Action的成员属性等值都是存到CompoundRoot下的。该CompoundRoot继承着ArrayList,因此它是List结构的。
public class CompoundRoot extends ArrayList {}
(2)OgnlContext
OgnlContext对象存储着相关的域对象:request、response、session等数据,并实现了Map接口,因此它是Map结构的。
为了让request、response等域对象可以存储多个值,值也是使用Map结构。
public class OgnlContext implements Map {}
6.小结
CompoundRoot保存着这样的数据:
- Action对象以及Action对象的成员属性数据;
- 使用ValueStack对象.push()进去的数据;
- 使用ValueStack对象.set()进去的数据;
- 其他代理对象的数据。
OgnlContext保存着这样的数据:
- 维护了CompoundRoot中所有的数据;
- request、response等域对象所有的数据。
7.OGNL表达式取值
- Struts2会将valueStack对象封装进request对象域中,传入JSP页面;
- valueStack存储着OgnlContext对象;
- OgnlContext对象维护了CompoundRoot对象的数据;
- CompoundRoot存储着Action等数据。
也就是说通过OgnlContext对象可以获取大部分我们需要的数据了。那么OGNL表达式是怎么取出OgnlContext对象中数据的呢??
JSP页面中取出数据的时候,它会先构建一个OGNL表达式,再解析表达式:
- 如果是CompoundRoot类的数据,表达式不需要带#号
- 如果不是CompoundRoot类的数据,表达式需要带#号
8.OGNL中特殊的符号
#:获取非根元素值 、 动态创建map集合;
$:在配置文件取值;
%:强制进行ognl解析。
