1.什么是OGNL
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。
Struts2框架使用OGNL作为默认的表达式语言。
OGNL就是EL(表达式语言)的升级版.
作用:Action和视图(JSP)之间数据交互的桥梁.
讲解OGNL之前,先得学习ValueStack
2.什么是ValueStack
值栈是对应每一个请求对象的轻量级的内存数据中心。
每一次请求的时候,都会创建一个新的ValueStack对象,该ValueStack对象封装了这一次请求相关的数据信息.
1).ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是实现了该接口的OgnlValueStack类,这个类是Struts2利用OGNL的基础。
2).ValueStack贯穿整个Action的生命周期(一次请求):每个Action类的实例都拥有一个ValueStack对象。 ValueStack相当于数据的中转站,在其中保存该次请求和当前Action对象和其他相关对象信息。
3).Struts2框架把ValueStack对象保存在名为“struts.valueStack”的request属性中。
新的请求:
ValueStack vs = …;
request.setAttribute(“struts.valueStack”,vs);
4,如何获取ValueStack.
ActionContext.getContext().getValueStack();
以上两种方式获取的是同一个ValueStack对象.
ValueStack内部结构
ValueStack对象中有两个很重要的属性,这两个属性就是ValueStack的主要内部结构:
root: 类型: CompoundRoot extends ArrayList : 表示栈的数据结构(后进先出,后进栈的数据在顶部)
context: 类型: Map: : 上下文
这两个是用来存数据的.
root:主要存储Action对象相关的数据信息.
Context:主要存储映射关系数据.(key-value)
context存在用root对象的引用(只要拿到context对象就可以获取到root对象):
context中还存在request、session、application、attr、parameters对象的引用。
获取到context,就可以获取ValueStack中所有的数据.
从root中获取数据: 直接使用属性名获取
---><s:property value="属性名/位置"/>
从context中获取数据: #key
---><s:property value="#key"/>
5.把数据放入ValueStack.
1).把数据放入root中:(栈,ArrayList.每次都要压在栈顶)
方式1:ValueStack对象.getRoot().add(0, Obejct val);//把数据压入栈顶
方式2:ValueStack对象.getRoot().push(Object val):等价于valueStack对象.getRoot().add(0, Obejct val);
方式3:ValueStack对象.set(String propertyName,Object value);
方式4.在Action中提供一个可访问的属性(getter方法).
所以推荐用方式4
一般的,把单个对象可放入root中,就在栈顶.
2).把数据放入context中:
方式1:ValueStack对象.getContext().put(String key,Object value); 太长了.
方式2:ActionContext对象.put(String key,Object value);
一般的:把集合中的数据放入context中.
6.如何从JSP中取出ValueStack中的数据:
此时必须使用Struts的标签.—>先引入Struts2标签
<%@ taglib uri="/struts-tags" prefix=“s”%>
Struts2的调试标签:<s:debug/> :主要用来观察数据在哪一个空间(root,context).
访问方式:<s:property value=“OGNL表达式”/>
1).获取root中数据:
若:放入root中的数据,没有属性名:<s:property value="[0].top"/>
若:放入root中的数据有属性名: <s:property value=“属性名”/>
2).把context中数据:
<s:property value="#key"/>
Action把数据共享在session中
== ActionContext.getContext().getSession().put(“USER_IN_SESSION”,“wtf”);==
<s:property value="#session.USER_IN_SESSION"/><br>
EL可以访问ValueStack中的数据:
不建议这么做:
为什么可以呢: Struts2重新包装而来请求对象.${msg}—><%=pageContext.findAttribute(“msg”) %>
StrutsRequestWrapper:先从ValueStack中取出数据,再放入request中.