一、OGNL和ValueStack(值栈)
Struts2数据共享.png1、Action把数据传递给JSP
- 1、在原生的servlet情况下
Servlet共享值:
request.setAttribute(String name,Object value);
JSP获取值:
通过EL来获取 ${name}
- 2、在Struts2中引入OGNL和ValueStack,把数据共享在某一个作用域对象中
Action共享值:
ActionContext.getContext().put(String name,Object value);
ActionContext.getContext().getSession().put(String name,Object value);
JSP获取值:
此时得依赖Struts2的标签:
<%@ taglib uri="/struts-tags" prefix="s" %>
再通过<s:property value=”OGNL的语法”>标签来获取数据.
2、OGNL
OGNL是Object Graphic Navigation Language(对象图导航语言[负责:对象和页面之间数据传递])的缩写,它是一个开源项目。
- Struts2框架使用OGNL作为默认的表达式语言
- OGNL就是EL的升级版
- OGNL是Action和视图JSP之间数据交互的桥梁
3、ValueStack(值栈)
- 1、ValueStack是对应每一个请求对象的轻量级的内存数据中心。
每一次请求的时候,都会创建一个新的ValueStack对象,该ValueStack对象封装了这一次请求相关的数据信息 - 2、ValueStack实际是一个接口,在Struts2中利用OGNL时,实际上使用的是现实了该接口OGNLValueStack类,这个类是Struts2利用OGNL的基础
- 3、ValueStack贯彻整个Action的生命周期(一次请求):每个Action类的实例都拥有一个ValueStack对象。ValueStack相当于数据的中转站,在其中保存该次请求和当前Action对象和其他相关对象信息
- 4、Struts2框架把ValueStack对象保存在名为"struts.valueStack"的request属性中。
4、获取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的内部结构
ValueStack对象中有两个很重要的属性,这两个属性就是ValueStack的主要内部结构
- root属性:CompoundRoot extends ArrayList:是栈的数据结构(后进先出,后进栈的数据在栈顶)。root中主要存储Action对象相关的数据信息。
- context属性:Map类型。主要存储映射关系数据(key-value),context中存在root对象的引用,只要拿到context对象就可以获取到root对象
- context中存在request、session、application、attr、parameters对象的应用。获取到context,就可以获取ValueStack中所有的数据
- 获取root中数据方式:直接使用属性名获取
<s:property value="属性名/位置"/>
- 获取context中获取数据方式
<s:property value="#key"/>
ValueStack内部结构.png
1、Struts2 Debug标签
- 1、jsp
<%@ taglib uri="/struts-tags" prefix="s"%>
使用debug标签
<s:debug></s:debug>
注意:在Struts2的 2.5.20版本中<s:debug>标签默认是关闭的,需要在struts.xml中打开开发者模式
<constant name="struts.devMode" value="true" />
-
2、debug内容
debug.png
2、共享数据到ValueStack中的root区域
- 1、使用add
private void rootData() {
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.getRoot().add(0, "Revan");
}
root_add.png
root区域存储数据结构变化,在没有存储数据到root区域时,key:com.revanwang.stack.StackAction在栈顶
- 获取数据
<s:property value="[0].top"/>
- 2、使用push
private void rootData_push() {
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.getRoot().push("Revan");
}
root_push![root_set.png](https://img.haomeiwen.com/i2338406/0f0a53e32ad1f42a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
.png
- 获取数据
<s:property value="[0].top"/>
- 3、使用set方法
private void rootData_set() {
ValueStack valueStack = ActionContext.getContext().getValueStack();
valueStack.set("name", "Revan");
}
- 获取数据
<s:property value="[0].name"/>
- 4、在Action中提供一个可访问的属性(getter方法),这个样保证Action在栈顶
@Setter
@Getter
private String name;
@Override
public String execute() throws Exception {
this.name = "123456";
return SUCCESS;
}
root_getter.png
- jsp中获取数据
<s:property value="name"/> //123456
3、共享数据到ValueStack中的context区域
- 1、存储到context区域
private void context() {
ActionContext.getContext().put("name", "Revan12345");
}
- 获取数据
<s:property value="#name"/>
- 存储位置 context.png
-
2、存储到context区域的session中
private void context_session() {
ActionContext.getContext().getSession().put("type", "Session-Revan");
}
- 获取数据
<s:property value="#session.type"/>
- 存储位置 context_session.png
-
3、存储到context区域的application中
private void context_application() {
ActionContext.getContext().getApplication().put("type", "Application-Revan");
}
- 获取数据
<s:property value="#application.type"/>
- 存储位置 application属性中
网友评论