【08】框架学习—浅谈Struts2中的值栈

来源:互联网 发布:金星妻子 知乎 编辑:程序博客网 时间:2024/06/01 18:17

1.OGNL表达式

1.1 OGNL(Object Graphic Navigation Language) 对象图导航语言

对象图,指以任意一个对象为根,通过OGNL可以访问与这个对象关联的其他对象,通过OGNL可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化功能。

1.2 Struts2框架使用OGNL作为默认的表达式语言

OGNL是一种比EL强大的表达式语言,xwork提供OGNL表达式。Jar包:ognl-3.0.5.jar

1.3 OGNL的五大类功能

支持对象方法调用。支持类静态的方法调用和值访问。访问OGNL上下文(OGNL context)和ActionContext。支持赋值操作和表达式串联。操作集合对象。

1.4 示例代码

这里写图片描述

1.5 Struts2框架种使用OGNL表达式

1 在JSP页面引入Struts2的标签库 <%@ taglib prefix=”s” uri=”/struts-tags” %>
2 使用示例:< s:property value=”#name”/>


2.值栈的概述

问题一:什么是值栈?

值栈相当Struts2框架的数据中转站,数据可以通过值栈进行存取。ValueStack是Struts2提供的一个接口,实现类是OnglValueStack。Action是多例的,一次请求创建一个Action实例,创建一个ActionContext对象(代表Action的上下文对象),同时会创建一个ValueStack对象。在ValueStack保存当前的Action对象和其它相关对象。Struts框架把ValueStack对象保存在名为“struts.valueStack”的请求属性request中。可获取:(ValueStack)request.getAttribute(“struts.valueStack”);

这里写图片描述


3.值栈的内部结构

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

3.1 值栈由两部分组成

root:Struts把动作和相关对象压入ObjectStack(List结构)中。context:Struts把各种各样的映射关系(Map类型对象)压入ContextMap中。

3.2 ContextMap

request:该Map中包含当前request对象中的所有属性。注意,request只是一个String类型的key值。session:该Map中包含当前session对象中的所有属性。application:该Map中包含当前application对象中的所有属性。parameters:该Map中包含当前请求的请求参数。如:?name=xxx&password=123attr:该Map按如下顺序检索某个属性:request,session,application。

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

CompoundRoot是ArrayList。OnglContext是Map。

3.4 OGNL表达式访问值栈中的数据

访问root中的数据时,不加“#”。访问context中的数据(如:request、session、application、attr、parameters等对象数据)必须加“#”。操作值栈默认指的是操作root栈。

4.ActionContext对象的关系

问题三:ValueStack和ActionContext是什么关系?

ValueStack对象是请求时创建的。ActionContext是绑定到当前的线程上,在每个拦截器或者Action中获取到的ActionContext是同一个。ActionContext中存在一个Map集合,该Map集合和ValueStack的context是同一个地址。ActionContext中有ValueStack的引用,可以获取到。

这里写图片描述


5.值栈对象的获取

问题四:如何获取到值栈对象?

三种方式:ValueStack vs1 = (ValueStack) ServletActionContext.getRequest().getAttribute(“struts.valueStack”);ValueStack vs2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);ValueStack vs3 = ActionContext().getContext().getValueStack();

6.值栈中保存数据

问题五:如何在值栈中保存数据(压栈)?

1>valueStack.push(Object obj);push方法的底层调用root对象的push方法(把元素添加到0位置)源码分析:

这里写图片描述

2>valueStack.set(String key, Object obj);底层会获取Map集合(Map不存在则创建一个),把Map集合压到栈顶,再把数据存入Map集合。源码分析:

这里写图片描述

补充:继续看一下retrieveSetMap()的实现。

这里写图片描述


7.值栈中获取数据

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

7.1 开始前认识:

访问root中数据,不需要 #。访问context其它对象数据加 #。如果向root中存入对象的话,优先使用push方法。如果向root中存入对象的话,优先使用set方法。

7.2 在OgnlContext中获取数据

Eg:request:<s:property value=”#request.username” />session:<s:property value=”#sesison.username” />application:<s:property value=”#application.username” />attr:<s:property value=”#attr.username” />parameters:<>s:property value=”#parameters.cid” />

7.3 示例如下:

这里写图片描述


8.EL表达式获取值栈中的数据

问题七:为什么EL也能访问值栈中的数据?
源码分析:
这里写图片描述

原创粉丝点击