OGNL表达式语言类似ELValueStackActionWord下载.docx
- 文档编号:19531857
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:71
- 大小:1.29MB
OGNL表达式语言类似ELValueStackActionWord下载.docx
《OGNL表达式语言类似ELValueStackActionWord下载.docx》由会员分享,可在线阅读,更多相关《OGNL表达式语言类似ELValueStackActionWord下载.docx(71页珍藏版)》请在冰豆网上搜索。
如下图,实际上该标签类似于EL表达式中的${}。
图-1
1.2.2.2个常用的OGNL表达式
OGNL表达式一共有8种使用方法,其中前2种要求大家必须掌握,是经常要用到的方式,后6种了解即可,下面我们来介绍这2种必须掌握的OGNL。
1、访问基本属性
∙语法:
属性名"
∙解释:
这种方式的作用是将Action中的基本属性直接显示到标签的位置,属性名指的是Action中的属性。
∙举例:
name"
2、访问实体对象
对象名.属性名"
这种方式的作用是将Action中的实体对象属性显示到标签的位置,对象名指的是Action中的实体对象,属性名指的是实体对象中的属性。
∙举例“<
user.userName"
可以看出,这两种访问Action的方式实际上与EL表达式用法完全一致,是最常用的,也是最容易掌握的2种方式。
1.2.3.6个需要了解的OGNL表达式
属性名[index]"
这种方式的作用是访问Action中的数组或集合的某元素,其中属性指的是Action中的数组或集合属性,index指的是数组或集合的下标。
langs[1]"
属性名.KEY"
这种方式的作用是访问Action中的Map类型的属性值,其中属性指的是Action中的Map类型属性,KEY指的是Map属性的key,即可以通过其key来直接输出对应的值。
msgMap.success"
OGNL和运算"
这种方式的作用是在访问Action数据后,可以对OGNL表达式返回的结果直接进行计算,并将计算结果输出于标签位置。
name+‘,你好‘"
OGNL.方法"
这种方式的作用是在访问Action数据后,可以直接调用OGNL表达式返回值的方法,并将最终的结果输出于标签位置。
name.toUpperCase()"
这种方式的作用是不访问Action的数据,而是直接使用OGNL表达式创建一个临时的集合,并返回输出于标签位置。
{1,2,3}"
这种方式的作用是不访问Action的数据,而是直接使用OGNL表达式创建一个临时的Map,并返回输出于标签位置
#{‘bj‘:
’北京‘,’sh’:
’上海’}"
2.1.ValueStack介绍
2.1.1.什么是ValueStack
ValueStack是Struts2中,Action向页面传递数据的媒介,ValueStack封装了Action的数据,并允许JSP通过OGNL来对其进行访问。
2.1.2.ValueStack原理
如下图,Struts2使用了ValueStack对OGNL组件进行了封装,其封装的实际上是改造后的OGNL,当然我们不关注改造的过程,只需要掌握改造后的OGNL在ValueStack中的运行原理即可。
ValueStack中首先封装了OGNL解析引擎,用于解析传入的OGNL表达式,其目的就是在页面上以标签+字符串的方式访问Java对象,从而降低了页面代码的开发难度,提升了页面代码的维护效率,而OGNL表达式传入引擎的时机我们在后面的Action基本原理中会讲到。
OGNL引擎可以访问2种类型的对象,一种是栈类型,另一种是Map类型。
1、栈
∙默认情况下,OGNL表达式访问的是这个栈,访问的规则是从栈顶向下依次以栈的每一级元素作为root对象来取值,直到取到值则返回,如果没有取到任何数据则返回null。
∙root对象就是JavaBean,只是在ValueStack中按照这种方式称呼而已。
OGNL访问root对象,其写法是直接从root对象的属性写起,比如以Action为root对象,访问Action中的user属性,那么OGNL表达式为user.userName。
∙栈中封装的是最常用的数据,通常情况下是Action和另外一个Struts2自身要使用的对象,其中Action位于栈顶。
此类型的目的是为了简化OGNL表达式,这一点我们在后面的迭代标签时会有更直观的体会。
2、Map
∙如果OGNL表达式以“#”开头,那么OGNL引擎会访问Map类型的对象,此时OGNL表达式的写法为#key,返回的值为该key在Map中对应的值,这种对象通常我们称之为context对象。
∙context对象用于封装程序的上下文数据,包含request、session、page、application等。
实际上,context对象封装的是完整的数据,也包含了action的数据。
∙context对象是完整的数据对象,有了它其实就足够了,但是Struts2设计出了栈,完全是处于简化OGNL表达式的目的,当然这种行为会增加一些理解的难度,我们需要重点关注栈里数据的变化,但这和使用的方便相比就不足挂齿了。
总体来说,由于context对象中的数据固定了,因此对context对象的访问比较简单和直接。
而栈中数据是会有所变化的,并且访问时也是自顶向下动态访问的,因此我们在学习ValueStack时要重点关注栈的结构和变化。
图-2
2.2.访问ValueStack
2.2.1.1、通过debug标签观察其结构
ValueStack的原理是比较抽象的,对于其结构的理解也不够直观。
对于这种情况,Struts2提供了一个调试标签,可以用于观察ValueStack的结构,该标签的效果如下图。
图-3
可以看出,该标签会在页面上生成一个debug链接,点击后会展开ValueStack的结构描述内容,其中包括栈的结构及数据、context对象的结构及数据。
该标签的语法比较简单,即<
debug/>
。
其作用仅仅是用于调试的,是给开发人员来使用的,当项目提交测试以及上线时,要删除该标记。
值得注意的是,该标签存在互斥性,在页面上如果写多个调试标签,实际上只有第一个是准确的,其他的标签内容有问题。
但鉴于该标签仅仅是给开发人员调试使用的,因此我们在了解这个规则的前提下,只要保持页面上只有一个调试标签即可正常使用。
2.2.2.2、输出栈顶
前面我们介绍了Struts2的显示标签,即<
这个标签有一种特殊的用法,可以直接输出栈顶的内容,语法为<
property/>
也就是说,将显示标签的value属性去掉,那么该标签将默认输出栈顶的内容。
2.2.3.3、访问context对象
Context对象是一个Map类型的对象,我们使用OGNL访问它的方式是固定的,即#key,返回的值是当前key在Map中对应的值。
2.2.4.4、迭代集合
我们可以使用Struts2的迭代标签结合着OGNL,来迭代Action中的集合属性,迭代集合标签的语法如下:
iteratorvalue="
users"
>
<
userName"
/s:
iterator>
users是OGNL表达式,自顶向下访问ValueStack栈中root对象的users属性,这里会从栈顶的Action对象取到该集合属性(List<
User>
users)值。
需要注意的是,在迭代的过程中,ValueStack的栈顶会发生变化,循环变量User会被压入栈顶,此时Action被压到栈的第二位,即栈顶由由原来的Action变为循环变量User,如下图
图-4
userName是OGNL表达式,自顶向下访问ValueStack栈中root对象的userName属性,这里会从栈顶的User对象取到userName属性值。
可以看出,这种动态访问栈中数据的方式,对我们的理解增加了一些难度,但是却可以简化循环内部的OGNL表达式,因为在循环时栈顶即为循环变量,我们以它为root写OGNL不用关注变量的名字了,而这部分代码在项目中是十分频繁出现的,因此牺牲一些理解难度的代价是完全值得的。
2.2.5.5、按数字迭代
有时候我们也需要按照数字的方式进行迭代,比如资费列表的分页功能。
对于这种方式,Struts2也有对应的标签支持,按照数字迭代的标签语法如下:
iteratorbegin="
from"
end="
to"
var="
k"
#k"
from/to是OGNL表达式,自顶向下访问ValueStack栈中root对象的from/to属性,这里会从栈顶的Action对象取到属性(intfrom=1,to=3)值。
与迭代集合一样,按数字迭代时,栈顶也会变为循环变量。
即在循环过程中,循环变量会被压入栈顶,此时Action被压到栈的第二位,如下图
图-5
需要注意的是,我们不能以数字做root对象,因此无法写OGNL访问栈顶的整数(数字内部没东西了,而访问root需要写其内部属性名)。
此时可以声明循环变量k,该声明会将循环变量加入context对象中(如k=2),这样我们就可以写#k这样的OGNL表达式来访问context对象,从而得到循环变量的值。
其实,我们也可以不写OGNL表达式,而是直接输出栈顶的值,即<
property/>
ValueStack结构看似复杂,但是需要我们重点关注的无非是栈顶的变化,而此变化也仅仅是在循环时发生,因此记住这唯一的变化情况即可,该情况我总结如下:
1、默认情况下栈顶为Action。
2、循环过程中,栈顶为循环变量。
迭代集合时,循环变量是集合中的对象,通常都是实体对象,即栈顶为实体对象,我们可以以实体对象为root来写OGNL表达式。
按数字迭代时,循环变量是数字,我们不能以数字为实体对象写OGNL,如果需要引用该数字,需要通过var声明变量名,然后以“#变量名”来引用它,这种情况下,我们是从context对象中取出的值。
3、循环结束后,栈顶变回Action。
2.3.Struts2对EL的支持
2.3.1.EL表达式如何访问ValueStack
Struts2将数据封装于ValueStack,默认使用OGNL表达式来取值,而在此之前我们却使用了EL表达式取Action的值,那么EL表达式是从哪里取的值,如何取的值呢?
实际上EL表达式也是从ValueStack中取到的值,因为Struts2把传递的数据都放于ValueStack中了。
但我们知道EL表达式的取值范围是page、request、session、application,而我们并没有把数据放入上述任何一个对象中,Struts2实现支持EL表达式的方式是以一个request的包装类来替代request,该包装类是request的子类,并覆写了它的getAttribute方法,在取值方法中先试图从原始request对象中取值,如果没有再从ValueStack中取值。
该request包装类的部分源码如下:
3.1.访问ValueStack
3.1.1.4、迭代集合
图-6
3.1.2.5、按数字迭代
图-7
3.2.Struts2对EL的支持
3.2.1.EL表达式如何访问ValueStack
4.1.重构资费列表
4.1.1.用Struts2标签+OGNL重构资费列表
重构资费列表页面,我们可以分2步进行。
首先重构数据显示区域,将原来的JSTL+EL替换成Struts2标签+OGNL,完成后刷新页面做单元测试。
然后重构分页部分,将原来你的JSTL+EL替换成Struts2标签+OGNL,完成后刷新做单元测试。
5.1.6大核心组件
5.1.1.6大核心组件关系
Struts2中包含6大核心组件,它们彼此关联、相互协作,共同处理了一次请求。
Struts2理论课实际上就是围绕这6大核心组件展开的,因此我们需要深刻的理解这6大核心组件的关系,这实际上也就是说明了Struts2的基本原理。
如下图,是Struts2中6大核心组件(红色)的关系:
图-8
针对这张图,我们再进一步解释6大核心组件的关系,这里我按照6大核心组件调用的顺序来加以说明。
值得注意的是,每次请求都会重新初始化除了FC之外的其他5大核心组件,即这些组件不是单例的,因此是线程安全的。
并且在最终请求结束时销毁这些组件,但在请求未结束之前,这些组件是存活的,因此在JSP的标签中,我们是可以使用OGNL表达式访问ValueStack对象中的数据的。
5.1.2.6大核心组件作用
1、FC
前端控制器,负责统一的分发请求。
2、Action
业务控制器,负责处理某一类业务。
3、ValueStack
Action与JSP数据交互的媒介。
4、Interceptor
拦截器,负责扩展Action,处理Action的共通事务。
5、Result
负责输出的组件。
6、Tags
标签,负责显示数据、生成框体。
===================================================
1.使用OGNL表达式-1
2.使用OGNL表达式-2
3.访问ValueStack-1
4.访问ValueStack-2
5.重构资费列表
1使用OGNL表达式-1
1.1问题
练习OGNL表达式的8种用法,即
1.访问基本属性
2.访问实体对象
3.访问集合/数组
4.访问Map
5.访问时运算
6.访问时调用方法
7.创建集合
8.创建Map
本案例中,先练习前2种用法,他们是最常用的。
1.2方案
在一次请求当中,我们可以在页面上使用OGNL访问Action中的基本属性和实体对象属性,这里重点是关注OGNL的写法,因此案例中Action和JSP可以简化处理。
我们可以复用StrutsDay01中的HelloWorld示例,在该示例的Action中追加基本属性和实体对象,在JSP中用OGNL进行访问。
1.3步骤
实现此案例需要按照如下步骤进行。
步骤一:
准备项目
选中项目StrutsDay01,右键复制,如下图:
粘贴项目StrutsDay01,如下图:
在弹出框中,将项目名改为StrutsDay02,如下图:
选中StrutsDay02,右键选择Properties,如下图:
在弹出框中,将此项目的web访问地址由StrutsDay01改为StrutsDay02,如下图:
修改HelloAction,删除其他演示代码,只保留业务方法即可,代码如下:
packageaction;
publicclassHelloAction{
publicStringsayHello(){
return"
success"
;
}
}
修改hello.jsp,删除其他演示代码,只保留基本的HTML结构即可,代码如下:
%@pagepageEncoding="
utf-8"
%>
html>
head>
/head>
body>
h1>
演示OGNL表达式<
/h1>
/body>
/html>
此时,项目StrutsDay02的结构如下图:
部署项目,启动tomcat并访问http:
//localhost:
8088/StrutsDay02/demo/hello,效果如下图则项目准备完毕:
步骤二:
使用OGNL访问Action基本属性
在HelloAction中追加任意基本属性并初始化,同时提供get、set方法,代码如下:
#cold_bold//基本类型
#cold_boldprivateIntegerid=1;
#cold_boldprivateStringname="
zhangsan"
#cold_boldpublicIntegergetId(){
#cold_boldreturnid;
#cold_bold}
#cold_bold
#cold_boldpublicvoidsetId(Integerid){
#cold_boldthis.id=id;
#cold_boldpublicStringgetName(){
#cold_boldreturnname;
#cold_boldpublicvoidsetName(Stringname){
#cold_boldthis.name=name;
在hello.jsp中,先通过taglib指令引入Struts2标签,然后在Struts2的显示标签上,使用OGNL表达式输出
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OGNL 表达式 语言 类似 ELValueStackAction