Java网课基础笔记(35)19-08-17

目录

 

值栈概述

值栈是什么?

值栈获取的方式

值栈操作(存值+取值)

值栈的存值机制

值栈的取值机制

值栈的默认搜索

值栈的存钱小结


值栈概述

值栈是什么?

值栈(ValueStack),是struts2的数据中转站,栈中自动保存了当前Action对象和其他相关对象(包括常用的Web对象的引用。如request、session、application等),也可以手动保存自己的数据对象,同时也可以随时随地将对象从值栈取出或操作(通过OGNL表达式)

值栈,实际是一个接口对象的称呼,接口是ValueStack类,现实类是OgnlValueStack类,该对象是struts2利用ognl的基础,或者说Struts2中Ognl使用都是基于值栈完成的。

Struts2框架将ValueStack对象保存在request域中,键为“struts.valueStack”,即使栈是request域中的一个对象,一个请求对应一个Action实例和一个值栈对象。

值栈获取的方式

  • 方式一:request.getAttribute("struts.valueStack");用的较少
  • 方式二:ActionContext.getContext().getValueStack();用的非常多--底层使用的还是方式一获取

编写ValueStackAction1.java

public class ValueStackAction1 extends ActionSupport {
	
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		//获取值栈
		//方式一:从request域中获取
		ValueStack vStack1= (ValueStack) ServletActionContext.getRequest().getAttribute("struts.valueStack");
		//方式二:通过ActionContext获取
		ValueStack vStack2=ActionContext.getContext().getValueStack();
		//获取的两次值栈是否是同一个对象?
		System.out.println(vStack1==vStack2);
		//当发出了两次请求(即运行两次action),两次情趣的值栈的hashcode不一致,表明每次请求都会重新创建值栈
		System.out.println(vStack1.hashCode());
		System.out.println(vStack2.hashCode());
		return NONE;
	}
}

配置struts.xml

<!-- 获取值栈的方式 -->
		<action name="vs1" class="struts2_03.valueStack.ValueStackAction1"></action>

测试结果

【示例】(重点)

目标:通过断点查看值栈的内部存储结构。

查看值是存在值栈的哪里?

编写ValueStackAction2.java

public class ValueStackAction2 extends ActionSupport{
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		ValueStack valueStack=ActionContext.getContext().getValueStack();
		//往值栈容器放数据
		//使用push方式存储
		valueStack.push("张艺兴");
		valueStack.push("王一博");
		valueStack.push("肖战");
		//使用set方式存储数据(K-V)
		valueStack.set("name", "小陈");
		valueStack.set("age", "22");
		//总结:使用push和set方法都会把数据放入root栈中
		return NONE;
	}

}

配置struts.xml

<!-- 查看值栈内部存储结构 -->
		<action name="vs2" class="struts2_03.valueStack.ValueStackAction2"></action>

设置断点,进入debug模式

往下走发现

是栈结构,先进后出。

值栈里有一个root栈,继承ArrayList,List结构,以栈的方式去存

使用root栈来存数据时,取数据比较麻烦?使用Map来取数据比较方便

编写ValueStackAction3.java

public class ValueStackAction3 extends ActionSupport {
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		ActionContext context=ActionContext.getContext();
		//通过put方式存储,放入map栈中
		context.put("name", "王一博");
		context.put("age", "22");
		return NONE;
	}

}

配置sruts.xml

<action name="vs3" class="struts2_03.valueStack.ValueStackAction3"></action>

设置断点,debug模式运行

总结

在值栈的内部有两个逻辑部分

ObjectStack(对象栈),由称为root栈,保存了Action的相关对象和动作,数据存储结构是List。

值栈操作(存值+取值)

值栈的存值机制

【回顾概念】

栈是一种数据结构,它按照先进后出的原则存储数据,即先进入的数据被压入栈底,最后进入的数据在栈顶,需要读取数据的时候,从栈顶开始弹出数据(即最后一个数据被第一个读出来)。

栈也被称为先进后出表,可进入插入和删除操作,插入称之为进栈(压栈)(push),删除称之为退栈(pop),允操作的一端称为栈顶(top),另外一端称为栈底(bottom)。栈底固定,而栈顶浮动。

对于栈只能每次访问它的栈顶元素。

值栈的取值机制

OgnlValueStack类包含两个重要的属性,一个root(CompoundRoot)和一个context(OgnlContext)。

OGNL Context是struts2的数据中心,其结构示意图为:

在这个OgnlContext对象中,有一个默认的顶层对象root(引用),俗称root栈,下面对象称之为Map栈。

对Ognl表达式的操作都是基于OgnlContext(map栈)对象,访问的规则如下:

  • 如果访问root栈内容(CompoundRoot 对象栈内容),不需要#,直接通过元素的名称为访问
  • 如果访问Map栈内容(如request、response、session、servletContext、attr、patameters),需要#key来引用访问,例如#request.name相当于request.getAttribute("name")

编写ValueStackAction4.java

public class ValueStackAction4 extends ActionSupport
{
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		ValueStack stack=ServletActionContext.getContext().getValueStack();
		stack.push("张艺兴");
		stack.push("王一博");
		//通过K-V形式把数据放入root栈中
		stack.set("name", "肖战");
		//通过map栈放数据
		ActionContext.getContext().put("age", "28");
		return SUCCESS;
	}

}

配置struts.xml

<action name="vs4" class="struts2_03.valueStack.ValueStackAction4">
		<result>/stack/valuestack.jsp</result>
		</action>

编写valuestack.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>访问值栈</h3>
<h3>如何访问这个匿名对象呢?获取栈顶元素</h3>
<%-- <s:property value="[0].top"/> --%>
<s:property value="top"/>
 <h3>如何还想获取第二个元素,如何获取呢?</h3>
<s:property value="[1].top"/>
 <h3>获取第三个元素,如何获取呢?</h3>
 <s:property value="[2].top"/>
<h3>获取map栈中的内容,要#</h3>
<s:property value="#age"/>
<h3>如何获取root栈中的有名字对象,不要#</h3>
<s:property value="name"/> 
</body>
</html>

测试结果(访问vs4.action)

值栈的默认搜索

在实际开发中,使用Ognl表达式时,会经常用到值栈的默认搜索,即自动搜索值栈,找到所需要的值。

即单个数据直接放入root栈,如果有K-V形式的数据,则放入map栈。

不加#的情况下,先搜索root栈,如果没有,在搜索map栈

加#的情况下,直接搜索map

值栈的存钱小结

值栈的主要作用就是数据的保存和获取(可以在任何地方获取)

注意要点:怎么存,就怎么取

存进root栈,就不通过#获取<s:property value="xxx"/>

存进map栈,就通过#获取<s:property value="#xxx"/>

  • 如何向值栈保存数据
  1. ValueStack.push(obj):保存数据到root栈顶-压栈(对象本身)-匿名
  2. ActionContex.getContext().put(key,value):保存数据到Map栈中
  3. ValueStack.set(key,value):将数据保存到root栈顶(数据对象自动被封装为Map来保存,栈顶是个map,map里面有个属性是对象)--有名字
  • ognl表达式如何获取值栈的数据

jsp页面获取

1.<s:property value="name"/>先搜索roo栈对象属性(getter方法,getAxx-->xxx),再搜索map到key

2.<s:property value="#name"/>搜索map的key

3.通过[index].top,指定访问root栈某层对象,例如[0].top栈顶对象

Action代码获取

编写ValueStackAction5.java

public class ValueStackAction5 extends ActionSupport
{
	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		//存root栈数据
		ServletActionContext.getContext().getValueStack().set("username", "胡歌");
		//取root数据
		String string1= ActionContext.getContext().getValueStack().findString("username");
		//存map栈数据
		ActionContext.getContext().put("username", "刘亦菲");
		//取map数据
		String string2=ActionContext.getContext().getValueStack().findString("#username");
		System.out.println("root栈"+string1+"--"+"map栈"+string2);
		return NONE;
	}

}

配置struts.xml

<action name="vs5" class="struts2_03.valueStack.ValueStackAction5"></action>

测试结果

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值