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表达式获取值栈中的数据了

Struts2【OGNL、valueStack】 随笔 第1张

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的存储结构是什么样的呢??

Struts2【OGNL、valueStack】 随笔 第2张

(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.小结

 Struts2【OGNL、valueStack】 随笔 第3张

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类的数据,表达式需要带#号

Struts2【OGNL、valueStack】 随笔 第4张

8.OGNL中特殊的符号

#:获取非根元素值 、 动态创建map集合;
$:在配置文件取值;
%:强制进行ognl解析。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄