java值栈_Java中的值栈

OGNL表示式使用 和 值栈

OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目。Struts2框架使用OGNL作为默认的表达式语言。

* xwork 提供OGNL表达式

* ognl-3.0.5.jar

OGNL 是一种比EL强大很多倍的语言

OGNL 提供五大类功能

1、支持对象方法调用,如xxx.doSomeSpecial();

2、支持类静态的方法调用和值访问

3、访问OGNL上下文(OGNL context)和ActionContext; (重点 操作ValueStack值栈 )

4、支持赋值操作和表达式串联

5、操作集合对象。

1、 使用OGNL访问 对象方法 和 静态方法

* OGNL 在jsp结合struts2标签库 使用 ,执行ognl表达式

调用 实例方法 : 对象.方法()  ----  

调用 静态方法 : @[类全名(包括包路径)]@[方法名]  ---

* 使用 静态方法调用 必须 设置struts.ognl.allowStaticMethodAccess=true

2、 访问OGNL上下文(OGNL context)和ActionContext

OGNL上下文(OGNL context) 对象-----值栈ValueStack

什么是值栈 ValueStack ?

值栈:简单的说,就是存放action的堆栈,当我们提交一个请求到服务器端action时,就有个堆栈,如果action在服务器端进行跳转,所有action共用一个堆栈,当需要保存在action中的数据时,首先从栈顶开始 搜索,若找到相同的属性名(与要获得的数据的属性名相同)时,即将值取出,但这种情况可能出现找到的值不是我们想要的值,那么解决此问题需要用TOP语法 和N语法来进行解决。

0

ValueStack 是struts2提供一个接口,实现类OgnlValueStack ----值栈对象 (OGNL是从值栈中获取数据的 )

每个Action实例都有一个ValueStack对象 (一个请求 对应 一个ValueStack对象 )

在其中保存当前Action 对象和其他相关对象 (值栈中 是有Action 引用的 )

Struts 框架把ValueStack对象保存在名为 “struts.valueStack” 的请求属性中,request中 (值栈对象 是 request一个属性)

valueStack vs = request.getAttribute("struts.valueStack");

问题二 : 值栈的内部结构 ?

值栈由两部分组成

ObjectStack  (root): Struts  把动作和相关对象压入ObjectStack中--List

ContextMap   (context): Struts 把各种各样的映射关系(一些Map类型的对象)压入ContextMap中

Struts 会把下面这些映射压入ContextMap中

parameters: 该Map中包含当前请求的请求参数?name=xxx

request: 该Map中包含当前request对象中的所有属性

session: 该Map中包含当前session对象中的所有属性

application:该Map中包含当前application对象中的所有属性

attr: 该Map按如下顺序来检索某个属性: request, session, application

ValueStack中 存在root属性(CompoundRoot)、context属性 (OgnlContext)

* CompoundRoot 就是ArrayList

* OgnlContext 就是Map

context 对应Map引入root对象

* context中还存在request、session、application、attr、parameters对象引用

* OGNL表达式,访问root中数据时 不需要#,访问request、session、application、attr、parameters对象数据 必须写#

* 操作值栈 默认指 操作root元素

问题三 : 值栈对象的创建 ,ValueStack 和ActionContext是什么关系 ?

值栈对象 是请求时 创建的

doFilter中prepare.createActionContext(request, response);

* 创建ActionContext对象过程中,创建 值栈对象ValueStack

* ActionContext对象 对ValueStack对象 有引用的 (在程序中 通过ActionContext获得 值栈对象 )

Dispatcher类serviceAction方法中 将值栈对象保存到request范围

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

问题四 : 如何获得值栈对象

获得值栈对象 有两种方法

ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);

ValueStack valueStack2 = ActionContext.getContext().getValueStack();

问题五: 向值栈保存数据 (主要针对 root)

两种方式

// 将数据保存root的索引0位置,放置到第一个元素ArrayList add(0,element);

valueStack.push("itcast");

// 在值栈创建参数map, 将数据保存到map中

valueStack.set("company", "数据");

在jsp中 通过查看值栈的内容

问题六: 在JSP中获取值栈的数据

访问root中数据 不需要#

访问 其它对象数据 加 #

通过下标获取root中对象

//取值栈顶对象

直接在root中查找对象属性 (自上而下自动查找)

valueStack:

在OgnlContext中获取数据

request:

session:

application:

attr:

parameters:

valueStack对象 保存在request范围, 值栈生命周期 就是request的生命周期 ,值栈的内部结构(root、ognlContext)

3、 值栈在开发中应用

主流应用 : 值栈 解决 Action 向JSP传递 数据问题

Action 向JSP传递数据处理结果 ,结果数据有两种形式

1) 消息String类型数据

this.addFieldError("msg", "字段错误信息");

this.addActionError("Action全局错误信息");

this.addActionMessage("Action的消息信息");

* fieldError 针对某一个字段错误信息 (常用于表单校验)、actionError (普通错误信息,不针对某一个字段 登陆失败)、actionMessage通用消息

在jsp中使用struts2提供标签 显示消息信息

2) 数据 (复杂类型数据)

使用值栈  valueStack.push(products);

哪些数据默认会放入到值栈 ???

1)每次请求,访问Action对象 会被压入值栈------- DefaultActionInvocation的init方法stack.push(action);

* Action如果想传递数据给JSP,只有将数据保存到成员变量,并且提供get方法就可以了

2)ModelDriven接口 有一个单独拦截器

在拦截器中 ,将model对象 压入了 值栈stack.push(model);

user.usernae ---------------?>

* 如果Action实现ModelDriven接口,值栈默认栈顶对象 就是model对象

4、 值栈的数据 通过EL访问

问题七:为什么 EL也能访问值栈中的数据

ActionContext.getContext().getSession().setAttribute("key","value");

${requestScope.username}----------->requst.getAttribute("username");------>重写getAttribute()方法,没有找到数据的情况下,继续找ValueStack

StrutsPreparedAndExecuteFilter的doFilter代码中request = prepare.wrapRequest(request);

* 对Request对象进行了包装 ,StrutsRequestWrapper

* 重写request的getAttribute

Object attribute = super.getAttribute(s);

if (attribute == null) {

attribute = stack.findValue(s);

}

访问request范围的数据时,如果数据找不到,去值栈中找

* request对象 具备访问值栈数据的能力 (查找root的数据)

5、OGNL表达式 常见使用

#、%、$符号使用

1)#的 使用

用法一  # 代表ActionContext.getContext()上下文

 ------>  ActionContext().getContext().getRequest().getAttribute("name");

#request

#session

#application

#attr

#parameters

用法二 : 不写# 默认在 值栈中root中进行查找

在root中查找name属性

* 查询元素时,从root的栈顶元素 开始查找, 如果访问指定栈中元素访问栈中第二个元素name属性

* 访问第二个元素对象

用法三 :进行投影映射 (结合复杂对象遍历 )

s:iterator标签在进行遍历时,会将var中保存的这个对象,在root中,和context中都放一份

所以在  value属性加不加#都可以访问

1)集合的投影(只输出部分属性

遍历集合只要name属性

2)遍历时,对数据设置条件

遍历集合只要price大于1500商品

---

3)综合

只显示价格大于1500商品名称

用法四: 使用#构造map集合

经常结合 struts2 标签用来生成select、checkbox、radio

使用#构造map集合 遍历

#{key:value,kye1:value1}

key : , value:  

2) %的使用

用法一: 结合struts2 表单标签使用, 通过%通知struts,%{}中内容是一个OGNL表达式,进行解析

是错误的

用法二: 设置ognl表达式不解析%{'ognl表达式'}

3)$的使用

用法一 :用于在国际化资源文件中,引用OGNL表达式

在properties文件msg=欢迎您, ${#request.username}

在页面

* 自动将值栈的username结合国际化配置信息显示

用法二 :在Struts 2配置文件中,引用OGNL表达式

${contentType}

*  ${contentType} 读取值栈中contentType数据,在Action提供getContentType因为Action对象会被压入值栈,

contentType是Action属性,从值栈获得

结论: #用于写ognl表达式获取数据,%控制ognl表达式是否解析 ,$用于配置文件获取值栈的数据

五、 struts2 标签库

tag-reference.html 就是struts2标签规范

1、 通用标签库 的学习

解析ognl表达式,设置默认值,设置内容是否HTML转义

对比c:set向四个数据范围保存数据

遍历值栈中数据

进行条件判断-------- elseif可以有多个

进行URL重写(追踪Session) ,结合s:param进行参数编码

*   

对一个链接 进行参数编码

* 下载MIME协议简介.txt

2、UI标签库的学习 (Form标签)

使用struts2 form标签 好处 : 支持数据回显 , 布局排版(基于Freemarker模板定义 )

struts2 表单标签value属性。 必须写%{}进行设值

使用struts2表单标签前, 必须配置StrutsPrepareAndExecuteFilter

表单标签

 ---   theme="xhtml" 默认布局样式

生成

生成

生成

生成

* struts2 除了支持JSP之外,支持两种模板技术Velocity (扩展名.vm )、Freemarker(扩展名.ftl)

生成多行文本框

生成一组checkbox

* 使用ognl构造Map(看到值和提交值 不同时)

*

生成一组radio

* 使用ognl构造List(看到内容和提交值 相同时)

*

生成一个

*

struts2 开发 密码框 默认不回显

3、 页面元素主题设置

default.properties  ----  struts.ui.theme=xhtml 设置struts2页面元素使用默认主题

struts.ui.templateSuffix=ftl 默认模板引擎Freemarker

修改主题

方式一 :只对当前元素有效

方式二 :

对form中所有元素有效

方式三 : struts.xml

 修改默认主题样式,页面所有元素都有效

优先级 : 方式一 > 方式二>方式三

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序栈(Sequence Stack)是一种基于数组实现的栈结构,可以进行入栈和出栈操作,下面是它的基本操作: 1. 初始化栈: 首先需要定义一个数组和一个指针,数组用来存储栈的元素,指针指向栈顶元素的下一个位置,初始时指针指向数组的第一个位置。具体实现如下: ``` #define MAXSIZE 100 // 定义栈的最大容量 typedef struct { int data[MAXSIZE]; // 存储栈的元素 int top; // 栈顶指针 } SeqStack; void InitStack(SeqStack *S) { S->top = 0; // 栈顶指针初始化为0 } ``` 2. 判断栈是否为空: 判断栈是否为空,只需要判断栈顶指针是否为0,如果为0,则表示栈为空,否则栈还有元素。具体实现如下: ``` bool StackEmpty(SeqStack S) { if (S.top == 0) { return true; } else { return false; } } ``` 3. 判断栈是否已满: 判断栈是否已满,只需要判断栈顶指针是否等于栈的最大容量,如果等于,则表示栈已满,否则栈还有空间可以添加元素。具体实现如下: ``` bool StackFull(SeqStack S) { if (S.top == MAXSIZE) { return true; } else { return false; } } ``` 4. 入栈操作: 入栈操作就是向栈添加一个元素,只需要将元素添加到栈顶指针所指向的位置,然后将栈顶指针加1即可。具体实现如下: ``` bool Push(SeqStack *S, int x) { if (StackFull(*S)) { return false; // 栈已满,无法入栈 } else { S->data[S->top] = x; // 将元素添加到栈顶指针所指向的位置 S->top++; // 栈顶指针加1 return true; } } ``` 5. 出栈操作: 出栈操作就是将栈顶元素弹出,只需要将栈顶指针减1,然后返回栈顶元素即可。具体实现如下: ``` bool Pop(SeqStack *S, int *x) { if (StackEmpty(*S)) { return false; // 栈为空,无法出栈 } else { S->top--; // 栈顶指针减1 *x = S->data[S->top]; // 返回栈顶元素 return true; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值