OGNL和ValueStack(值栈) |
后台给JSP页面传输共享数据:
把数据共享在某一个作用域对象中.
Servlet:
request.setAttribute(String name,Objectvalue);
JSP:
通过EL来获取.
${name}
------------------------------------
1,通过HttpServletRequest对象传递;页面上使用EL表达式获取;
优点:易于理解;
缺点:过于依赖Servlet函数;操作复杂,页面如果有大量数据,非常麻烦;页面取数据麻烦;
-----------------------------------------------------------------------------
在Strtus2中:引出OGNL和ValueStack.
把数据共享在某一个作用域对象中.
Action:
ActionContext.getContext().put(Stringname,Object value);
ActionContext.getContext().getSession().put(String name,Object value);
JSP:
此时得依赖Struts2的标签:
<%@ taglib uri="/struts-tags"prefix="s" %>
再通过<s:property value=”OGNL的语法”>标签来获取数据.
1.什么是OGNL
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。
Struts2框架使用OGNL作为默认的表达式语言。
EL(表达式语言),OGNL就是EL的升级版.
作用:Action和视图(JSP)之间数据交互的桥梁.
讲解OGNL之前,先得学习ValueStack.
--------------------------------------------------------------
2.什么是ValueStack
值栈是对应每一个请求对象的轻量级的内存数据中心。
每一次请求的时候,都会创建一个新的ValueStack对象,该ValueStack对象封装了这一次请求相关的数据信息.
一个用户请求--->一个Action对象--->---一个请求对象------->一个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);
如何获取值栈对象 |
3,如何获取ValueStack.
方式1: 因为ValueStack在请求中,属性名为:struts.valueStack.
ValueStack vs =request.getAttribute("struts.valueStack");
ValueStack vs =ServletActionContext.getRequest().getAttribute("struts.valueStack");
ValueStack vs =ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
方式2: 通过ActionContext对象获取
ValueStack vs =ActionContext.getContext().getValueStack();
以上两种方式获取的是同一个ValueStack对象.
值栈的内部结构 |
4.ValueStack内部结构
ValueStack对象中有两个很重要的属性,这两个属性就是ValueStack的主要内部结构:
------------------------------------
root: 类型: CompoundRoot extends ArrayList : 栈的数据结构(后进先出)
context: 类型: Map: : 上下文
root:主要存储Action对象相关的数据信息.
Context:主要存储映射关系数据.(key-value).
context中还存在request、session、application、attr、parameters对象的引用。
获取到context,就可以获取ValueStack中所有的数据.
从root中获取数据: 直接使用属性名获取. ---><s:property value="属性名"/>
从context中获取数据:#key ---><s:propertyvalue="#key"/>
值栈root区域值的存取 |
5.把数据放入ValueStack.
1).把数据放入root中:(栈,ArrayList.每次都要压在栈顶)
方式1:ValueStack对象.getRoot().add(0, Obejctval);//把数据压入栈顶
方式2:ValueStack对象.getRoot().push(Objectval):等价于valueStack对象.getRoot().add(0, Obejct val);
方式3:ValueStack对象.set(StringpropertyName,Object value);
方式4.在Action中提供一个可访问的属性(getter方法).
一般的,把单个对象可放入root中,就在栈顶.
6.如何从JSP中取出ValueStack中的数据:
此时必须使用Struts的标签.--->先引入Struts2标签
<%@ taglib uri="/struts-tags" prefix="s"%>
访问方式:<s:propertyvalue="OGNL表达式"/>
1).获取root中数据:
若:放入root中的数据,没有属性名:<s:propertyvalue="[0].top"/>
若:放入root中的数据有属性名: <s:property value="属性名"/>
值栈context区域值的存取 |
5.把数据放入ValueStack.
把数据放入context中:
方式1:ValueStack对象.getContext().put(Stringkey,Object value); 太长了.
方式2:ActionContext对象.put(String key,Objectvalue);
一般的:把集合中的数据放入context中.
6.如何从JSP中取出ValueStack中的数据:
此时必须使用Struts的标签.--->先引入Struts2标签
<%@ taglib uri="/struts-tags" prefix="s"%>
访问方式:<s:propertyvalue="OGNL表达式"/>
1).把context中数据:
<s:property value="#key"/>
--------------------------------------
EL可以访问ValueStack中的数据:(不建议使用)