struts,ognl,valuestack
浅析struts2中的OGNL和 ValueStack
要了解Struts2与OGNL表达式的关系,我们必须先搞清楚以下三个概念:
(1)ActionContext 它是Action运行的上下文环境,Action的多项设置都存放在此,我们每一次Action调用都会创建一个ActionContext 。通常情况下我们可以通过静态方法getContext()来
获得Action上下文,进而进行其它操作,比如说可以得到request session application
(2)ValueStack 此对象主要是由OGNL框架实现,具体的实现类是com.opensymphony.xwork2.
Util.ValueStack; 它主要包含了一个Map类型的Context对象,和最重要的getValue与findValue方法,以及peek、pop等栈所特有的方法。
Strut 2的Action类通过属性可以获得所有相关的值,如请求参数、Action配置参数、向其他Action传递属性值(通过chain结果)等等。要获得这些参数值,我们要做的唯一一件事就是在
Action类中声明与参数同名的属性,在Struts 2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。
要完成这个功能,有很大程度上,Struts 2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当Struts 2接收到一
个.action的请求后,会先建立Action类的对象实例,并且将Action类的对象实例压入ValueStack对象中(实际上,ValueStack对于相当一个栈),而ValueStack类的setValue和findValue方
法可以设置和获得Action对象的属性值。Struts 2中的某些拦截器正是通过ValueStack类的setValue方法来修改Action类的属性值的。如params拦截器用于将请求参数值映射到相应成Action
类的属性值。在params拦截器中在获得请求参数值后,会使用setValue方法设置相应的Action类的属性。
从这一点可以看出,ValueStack对象就象一个传送带,当客户端请求.action时,Struts 2在创建相应用Action对象后就将Action对象放到了ValueStack传送带上,然后ValueStack传送带会
带着Action对象经过若干拦截器,在每一拦截器中都可以通过ValueStack对象设置和获得Action对象中的属性值。实际上,这些拦截器就相当于流水线作业。如果要对Action对象进行某项加
工,再加一个拦截器即可,当不需要进行这项工作时,直接将该拦截器去掉即可。
需要注意的是我们访问这类对象时是不需要加入#的,因为它是根对象,所以不能加#,加了以后就不能访问到了。比如我们在Action中做了如下操作ActionContext.getContext
().getVlaueStack()
.setVlaue(“MM”,”这是信息”),然后在页面就只可以通过<s:property value=”MM” />就可以了。
(3) Stack Context(map): stack上下文,它包含一系列对象,包括request/session/attr
/application map等,也是用来存值的。struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:
|--request
|--application
context map---|--OgnlValueStack(root) [ user, action, OgnlUtil, ... ]
|--session
|--attr
|--parameters
在Struts2中,采用标准命名的上下文(Context)来处理OGNL表达式。处理OGNL的顶级对象是一个Map(也叫context map,它实际上是ActionContext中的一个对象,也叫context),在这个
contxt属性中我们分别放置了context.put(“常量REQUEST”,new HashMap<String,Object>()); context.put(“常量APPLICATION”,new HashMap<String,Object>()); 等等,同样我们在其
中也放置了一个名叫vsMap的对象(自己随便取了个名字):来看下面两个相关的方法
public void setValueStack(ValueStack stack) { put(VALUE_STACK, stack); }
public void put(String key, Object value) { context.put(key, value); }
我们可以看到这个ValueStack同样设置到了上下文对象中[实际上使用的ValueStack中的context属性]。 而ValueStack中除了这个Map以外,还维护一个ComponentRoot对象,它实际上用来存
放我们的一个List集合,它还要维护一个栈即Stack, 以期让我们进行后续的操作。
Struts2框架把我们的ActionContext设置为OGNL 的上下文环境,凡是此环境中的值我们都应该通过#key的方式来进行访问,所以request,session等需要加前缀,又因为Struts2将我们的
ValueStack作为OGNL的根对象,所以我们访问其中的内容只能通过非#的方式来进行。
Action的实例,总是放到value stack中。因为Action放在stack中,而stack是root(根对象),所以对Action中的属性的访问就可以省略#标记。但是,要访问ActionContext中其它对象的属
性,就必须要带上#标记,以便让OGNL知道,不是从根对象,而是从其它对象中去寻找。具体的代码可以这样理解:
而我们直接通过ActionContet.getContext().put(“属性名”,“值”);放入的数据放在了一个ActionContext 的context对象(OGNL上下文)和ValueStack对象的context对象共同引用的一
个Map对象中,所以我们既可以通过#key也可以直接通过key来进行访问。
那么访问Action中的属性的代码就可以这样写
<s:property value="postalCode"/> 其它ActionContext中的非根对象属性的访问要像下面这样写:
<s:property value="#session.mySessionPropKey"/> or
<s:property value="#session['mySessionPropKey']"/> or
<s:property value="#request['myRequestPropKey']"/> 对Collection的处理,内容就很简单。
<s:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}" />
这是处理List。这个代码在页面上建立一个下拉选项,内容是list中的内容,默认值是name2.
处理map
<s:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}" />
需要注意的是,判断一个值是否在collection中。我们要使用in或者not in来处理。
<s:if test="'foo' in {'foo','bar'}">
muhahaha
</s:if>
<s:else>
boo
</s:else>
另外,可以使用通配符来选择collection对象的子集。
?——所有匹配选择逻辑的元素
^——只提取符合选择逻辑的第一个元素
$——只提取符合选择逻辑的最后一个元素
person.relatives.{? #this.gender == 'male'}
`````````````````````````````````````````````````````````````````````````````````
设值计算
Struts2中使用OGNL进行设值计算,就是指View层传递数据到Control层,并且能够设置到相应
的Java对象中。这个过程从逻辑上说需要分成两步来完成:
1. 对于每个请求,都建立一个与相应Action对应的ActionContext作为OGNL的上下文环境和
ValueStack,并且把Action压入ValueStack
2. 在请求进入Action代码前,通过某种通用的机制,搜集页面上传递过来的参数,并调用OGNL相关的
代码,对Action进行设值。
上面的第一个步骤,在处理URL请求时完成,而第二个步骤由struts2内置的拦截器完成。
“#”主要有三种用途:
1. 访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:
名称
作用
例子
parameters
包含当前HTTP请求参数的Map
#parameters.id[0]作用相当于request.getParameter("id")
request
包含当前HttpServletRequest的属性(attribute)的Map
#request.userName相当于request.getAttribute("userName")
session
包含当前HttpSession的属性(attribute)的Map
#session.userName相当于session.getAttribute("userName")
application
包含当前应用的ServletContext的属性(attribute)的Map
#application.userName相当于application.getAttribute("userName")
attr
用于按request > session > application顺序访问其属性(attribute)
#attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
2. 用于过滤和投影(projecting)集合,如books.{?#this.price<100};
3. 构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。
“%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。[既字符串不是输出到页面,而是作为某个属性的取值],如下面的url就是一个取值。
例如在Ognl.jsp中加入以下代码:
4. <hr />
<h3>%的用途</h3>
<p><s:url value="#foobar['foo1']" /></p>
<p><s:url value="%{#foobar['foo1']}" /></p>
$符号 $符号主要有两个方面的用途。
(1) 在国际化资源文件中,引用OGNL表达式,例如国际化资源文件中的代码:reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间。
(2) 在Struts 2框架的配置文件中引用OGNL表达式,例如下面的代码片断所示:
<validators>
<field name=”intb”>
<field-validator type=”int”>
<param name=”min”>10</param>
<param name=”max”>100</param>
<message>BAction-test校验:数字必须为${min}为${max}之间!</message>
</field-validator>
</field>
</validators>
struts,ognl,valuestack相关推荐
- struts OGNL表达式
OGNLContext对象有两部分构成 一部分是ROOT:可以放置任何对象作为ROOT 另外一部分Context:必须是Map形式(键值对) OGNL表达式操作 package cn.future.a ...
- Struts(十一):OGNL表达式(二)
Map栈 :request,session,application的一个属性值或一个请求参数的值. 若想访问ContextMap里的某个对象的属性,可以使用以下几种之一: #object.proper ...
- 深入分析JavaWeb Item48 -- Struts2中OGNL表达式与ValueStack
一.OGNL表达式 1.OGNL表达式介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作 ...
- OGNL中的s:property /标签
要使用<s:property/>标签就要引入标签库<%@taglib prefix="s" uri="/struts-tags"%> Ⅰ ...
- struts2之OGNL用法
浅析OGNL OGNL是Object-GraphNavigation Language的缩写,是一种功能强大的表达式语言 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对 ...
- Struts(十六):通过CURD来学习Struts流程及ModelDriven的用法
背景: 从一个Member的增删改查,来了解Struts2的运行原理及学习ModelDriven拦截器.Preparable拦截器. 新建项目实现列表的展示及删除功能: web.xml <?xm ...
- struts2教程(9)--OGNL表达式使用
OGNL表示式使用和值栈 一.介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的 ...
- WEB Struts2 中OGNL的用法
2019独角兽企业重金招聘Python工程师标准>>> User对象属性获取 如User中有username和password字段 获取username属性<s:propert ...
- Struts2标签库和OGNL
学习内容 Struts 2标签库 OGNL 能力目标 熟练使用Struts 2常用标签 熟练使用OGNL 本章简介 前面我们编写的案例使用的都是HTML标签,这些标签并不能很好的与Struts 2框架 ...
最新文章
- Python游戏开发,pygame模块,Python实现愤怒的小鸟【附带源码】
- Interview:算法岗位面试—11.17下午上海某网**软件公司(上市)技术面之比赛考察、目标检测算法、视频分析算法考点
- mysql日期/时间转换为字符串
- Equipment download - No data contained in BDoc
- hdu_1728_逃离迷宫(bfs)
- 用友u8年度账文件服务器错误,用友u8erp软件出纳管理模块年度数据结转常见问题...
- python文件管不了_Python对文件和文件路径的管理
- 零基础小白前端学习之初始CSS
- MCU破解技术分析(一)
- Win10启用linux子系统(Linuxer福利)
- JQuery.Gantt(甘特图) 开发指南
- 相机标定与三维重建原理
- IntelliJ IDEA自动引入jar包
- Tableau中的筛选器
- 刷题总结——松鼠的新家(bzoj3631)
- 离散数学及其应用学习笔记——主定理(Master Theorem)的证明
- 行式和列式存储说明以及OLAP特点介绍
- 天之痕MV-三个人的时光
- python攻击某个wifi设备使断网_Python实现WiFi断线自动重连的方法详解
- 安桥TX-NR509高清功放无声、HDMI故障维修记录
热门文章
- PyInstaller库的安装、使用
- Spring IoC 源码系列(三)Spring 事件发布机制原理分析
- VTK:可编程源用法实战
- wxWidgets:wxStringBufferLength类用法
- GDCM:gdcm::EquipmentManufacturer的测试程序
- Boost::context模块fiber的throw测试程序
- ITK:侵蚀二进制图像
- ITK:获取类型的基本信息
- OpenCV cv :: Mat的串行输出功能的实例(附完整代码)
- QT集成QML和JavaScript