java actioncontext_struts2(四) ognl表达式、值栈、actionContext之间的关系

今天来说说ognl表达式在struts2中的运用。

--WZY

一、什么是Ognl?

通过百度百科查询到的解释,其中详细的说明了OGNL的作用。

04096f6686c95ccc20fe2b21db1c9121.png

下面我们就对OGNL这5个作用进行讲解

1、存取对象的任意属性,简单说就是对javabean进行操作(重要)

2、调用对象方法。

3、调用类的静态方法

4、索引数组元素

5、操作集合(重 要)

二、OGNL的功能实现

操作之前必须知道如何使用OGNL表达式,并且了解OGNL表达式的取值范围只能在其context和root中,格式为

Ognl.getValue(expression,context,root);

//expression:为我们编写的ognl表达式,从后两个参数中获取值,获取规则会从下面的例子中详细讲解

//context:ognl的上下文,类型为map,

//root:ognl的根,可以为javabean、list、map、.... 等等很多值

2.1、对javabean进行操作

User.java

6e4ac44d6dcabaf028a2989f0dcd1bbf.png

Address.java

f428af10d0dd444c47516b267406b1e0.png

获取javabean中的属性值

56603529dac33c8cf1f9b2b30cf837bd.png

获取javabean中的对象的属性值

babdd0ac96a0edded99779cb02390531.png

对javabean中的属性进行赋值操作

52372c0b342d37094a347f4a76a42aad.png

2.2、调用对象方法

b7a2197dcc18413f9ce417373caac95d.png

2.3、调用类的静态方法或属性

61f65e60d3c0cf666cd7c582fe4c23d7.png

2.4、索引数组元素

a40b73b41273f115580663990b49d3c1.png

2.5、操作集合

操作list集合,list结合本质就是一个数组,所以从list中读取数据跟对数组的操作是一样的。

6121d5a932b760c9b94bb66f20627e00.png

操作map集合

2d643f076b5f64409a93d9511ef6311a.png

创建list集合

23198021723ef7c8aeca98f68e2ae9d2.png

创建map集合

464d11d532700f0a304df5a9aef5ca0f.png

2.6、其他用法,使用数学运算符,使用“,”号连接表达式,in与not in运算符,投影、过滤等操作就不讲解了,都非常简单,重点掌握上面的即可。

三、OGNL与struts2的结合

上面说了那么一大堆的OGNL的使用功能,我们也感受到了他的强大,啥都能取出来,表达式啥都能做,但是在struts2中它是如何使用的呢?

OGNL中的上下文即struts2中的actionContext

OGNL中的root即struts2中的valueStack

actionContext和valueStack是什么,他们之间什么关系?

3.1、ActionContext和valueStack(重要)

ActionContext:

充当OGNL的context。是action的上下文,也可以叫做action的数据中心,本质是一个map,在其中,所有的数据都存放在这里,那其中到底存放了哪些东西呢,actionContext中存放数据的方式又是怎样的?

actionContext是一个map,所以其中都是以键值对的形式存储对象,如下图所示,

request、session、application这种我们熟知的作用域,注意是作用域,而不是对象,

paramters:这个是表单提交的参数,全部都会放到这个map中,

attr(attributes):三个作用域所有的属性都会放在该map下,如果有重复的,那么以request域中的为准。

VALUE_STACK:值栈,存放着valueStack对象,也就是说,通过ActionContext能够获取到valueStack。

如果我们使用actionContext.put();  那么会将该键值对直接放入到ActionContext下,

注意:除了request外,其他都可以直接通过getXxx()获得。而想要获取request作用域,必须通过key值的方式来获取。ActionContext.getContext().get("request");   为什么这样呢?因为struts2对request进行了增强。从这里actionContext中是不能直接获取到的,request进行了怎样的增强呢?比如在actionContext中put了一个普通的key和value,该键值对并没有在request域中,但是在jsp中,通过在request域查找key,也能找到该键值对,底层进行了两步:第一步:从request域中查找数据,第二步:如果没有找到,将从值栈中执行findValue()。  这样就解释了为什么通过ActionContext不能直接获取request,并且为什么不在request作用域中的数据,而通过在request域中查找也能够获取到。

e2e881aec9e6d420affaca637cafd78b.png  

8d2244a5d452e8a5ff111912ab237560.png

valueStack:值栈,本质是一个ArrayList,作用,充当ognl的root,给一次请求中共享数据的功能。

内部图

c5c081a209a41a9d415f71c31d35b681.png

root:源码中的名称为CompoundRoot,它也是一个栈,而每次值栈中入栈和出栈等操作其实就是对CompoundRoot进行对应的操作。

Context:对actionContext的引用,也就是通过valueStack也能够获取到上下文,通过getContext();

在我们访问一个action时,会将action加入到栈顶,也就是action会在CompoundRoot的栈顶,而我们提交的各种表单参数(充当了ognl表达式)会在valueStack从顶向下查找对应的属性进行赋值。这就是值栈的作用。

值栈的操作

这里提一下,知道了值栈的内部结构图,那么就好理解了。

action中手动向valueStack中放数据。

ActionContext.getContext().getValueStack().push(xxx);  //一般是javabean,这样放是放在root中,因为push操作是对栈进行操作,也就是对root进行操作

ActionContext.getContext().getValueStack().set(key,value);  //任意值,以key-value的形式放入到了root中。

jsp获取

push存放,在root下,直接使用属性获取即可

set存放,通过属性也可以直接获得。这里要排除一个误区,就是不要觉得set方式是以键值对的方式存放,就觉得是放入了context中,并没有,还是在root中锝

context操作

ActionContext.getContext().put(key,value);  //存放在actionContext中,也就是OGNL的context中

JSP获取:三种方式进行获取

#key获取。

直接使用key获取,因为值栈中也有context。只不过要从栈顶中的root开始找,然后在从context中查找

#request获取。因为struts2对request进行了增强,如果request域中找不到,则使用findValue(),从值栈中的root开始一路往下找。

3.2、ActionContext和valueStack的关系(重要)

你中有我,我中有你。

f6961462caef86606e84a66fe1ad3ff0.png

也就是说,通过valueStack可以获取到actionContext,通过ActionContext也可以获取到valueStack。

valueStack是对root进行操作,而actionContext是对context进行操作。(root和context是OGNL中的根和上下文)

获取值栈的方式:

ActionContext.getContext.getValueStack();//常用

ActionContext.getContext.get("VALUE_STACK");

request.getAttribute("VALUE_STACK");    //这个为什么可以?因为request进行了增强。详情看上面的解释。

获取actionContext的方式

ActionContext.getContext();  //常用

valueStack.getContext();

3.3、struts2不同的地方使用OGNL表达式获取数据

3.3.4、在jsp页面中

大部分都会在这里使用,因为jsp就是显示数据的地方,在struts2中有很多s标签,通过s标签和OGNL表达式一起配置使用,就能拿到想要的数据了。而OGNL的表达式的编写在最开始就已经讲解过了,context就是actionContext,root就是valueStack,剩下表达式就看我们需要什么了。标签的讲解会在下一章

3.3.5、在struts.xml中

在struts.xml中有时候也需要用到OGNL表达式去拿一些数据。比如,在result中设置stream时,就需要从action中获取流,而action可以看成是javabean,又在栈顶,所以直接使用OGNL表达式就能够获取到,但是注意特殊的,如果在你直接编写ognl表达式时struts2不能够区分出这是ognl表达式还是普通文本,那么就需要使用${}来表明该段文本是ognl表达式

dc15df837fc1873a19fcd5f0c2e53d64.png

四、总结

struts2我觉得最重要的两点,

一、理解它的架构图,知道大概的流程,

二、该篇文章讲解的值栈,actionContext,ognl的关系,

这两个弄懂了,基本上没什么难得倒我们了,在写三到四篇文章就可以把struts2给结束掉,还差的知识点有,s标签的使用、国际化、还有文件上传和下载的功能详细讲解,最后通过小项目将struts使用起来,就完了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值