今天来讲说ognl表达式在struts2中的运用。java
--WZYexpress
1、什么是Ognl?数组
经过百度百科查询到的解释,其中详细的说明了OGNL的做用。session
下面咱们就对OGNL这5个做用进行讲解架构
一、存取对象的任意属性,简单说就是对javabean进行操做(重要)app
二、调用对象方法。jsp
三、调用类的静态方法spa
四、索引数组元素3d
五、操做集合(重 要)xml
2、OGNL的功能实现
操做以前必须知道如何使用OGNL表达式,而且了解OGNL表达式的取值范围只能在其context和root中,格式为
Ognl.getValue(expression,context,root);
//expression:为咱们编写的ognl表达式,从后两个参数中获取值,获取规则会从下面的例子中详细讲解
//context:ognl的上下文,类型为map,
//root:ognl的根,能够为javabean、list、map、.... 等等不少值
2.一、对javabean进行操做
User.java
Address.java
获取javabean中的属性值
获取javabean中的对象的属性值
对javabean中的属性进行赋值操做
2.二、调用对象方法
2.三、调用类的静态方法或属性
2.四、索引数组元素
2.五、操做集合
操做list集合,list结合本质就是一个数组,因此从list中读取数据跟对数组的操做是同样的。
操做map集合
建立list集合
建立map集合
2.六、其余用法,使用数学运算符,使用“,”号链接表达式,in与not in运算符,投影、过滤等操做就不讲解了,都很是简单,重点掌握上面的便可。
3、OGNL与struts2的结合
上面说了那么一大堆的OGNL的使用功能,咱们也感觉到了他的强大,啥都能取出来,表达式啥都能作,可是在struts2中它是如何使用的呢?
OGNL中的上下文即struts2中的actionContext
OGNL中的root即struts2中的valueStack
actionContext和valueStack是什么,他们之间什么关系?
3.一、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域中查找也可以获取到。
valueStack:值栈,本质是一个ArrayList,做用,充当ognl的root,给一次请求中共享数据的功能。
内部图
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.二、ActionContext和valueStack的关系(重要)
你中有我,我中有你。
也就是说,经过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.三、struts2不一样的地方使用OGNL表达式获取数据
3.3.四、在jsp页面中
大部分都会在这里使用,由于jsp就是显示数据的地方,在struts2中有不少s标签,经过s标签和OGNL表达式一块儿配置使用,就能拿到想要的数据了。而OGNL的表达式的编写在最开始就已经讲解过了,context就是actionContext,root就是valueStack,剩下表达式就看咱们须要什么了。标签的讲解会在下一章
3.3.五、在struts.xml中
在struts.xml中有时候也须要用到OGNL表达式去拿一些数据。好比,在result中设置stream时,就须要从action中获取流,而action能够当作是javabean,又在栈顶,因此直接使用OGNL表达式就可以获取到,可是注意特殊的,若是在你直接编写ognl表达式时struts2不可以区分出这是ognl表达式仍是普通文本,那么就须要使用${}来代表该段文本是ognl表达式
4、总结
struts2我以为最重要的两点,
1、理解它的架构图,知道大概的流程,
2、该篇文章讲解的值栈,actionContext,ognl的关系,
这两个弄懂了,基本上没什么可贵倒咱们了,在写三到四篇文章就能够把struts2给结束掉,还差的知识点有,s标签的使用、国际化、还有文件上传和下载的功能详细讲解,最后经过小项目将struts使用起来,就完了。