OGNL是一个开源项目。它的存在就是为了取代页面中的java脚本,简化数据的访问。
1.表达式
2.上下文
3.根对象(ROOT对象)
OGNL表达式是围绕**OGNL上下文**进行的;OGNL实际上是一个Map对象,属于ognl.OgnlContext类,在它里面可以存放多个JavaBean对象。而上下文中会存在一个根对象,访问根对象可以直接通过名称或者属性访问,而无需加任何符号。而如果要访问上下文中其它JavaBean对象则需要使用**#**符号。
Struts2中将ActionContext作为上下文,将ValueStack(值栈)作为根对象。直接就可以使用ognl表达式来访问ActionContext。
OGNL上下文实际上就是一个Map对象,由ognl.OgnlContext类表示。它里面可以存放很多个JavaBean对象。它有一个上下文根对象。
上下文中的根对象可以直接使用名来访问或直接使用它的属性名访问它的属性值。否则要加前缀“#key”。
Struts2中的OGNL表达式语言的根对象是一个ValueStack,ValueStack中的每一个对象都被视为根对象。
Struts2框架将实例化的Action对象放入ValueStack中,如果是Action链,则多个Action都存在于ValueStack中。而ValueStack中除了Action外,Struts2框架还将parameters,request,response,session,application,attr等对象放到ActionContext中,访问这些对象需要加前缀#。
Struts2的标签库都是使用OGNL表达式来访问ActionContext中的对象数据的
在Strust2中,有一个内置对象叫ActionContext,通过该对象可以获得之前Servlet中的对象,比如:requst对象,response对象…
那么为什么可以通过ActionContext获得那些对象呢?
那是因为在ActionContext内容引用了那些对象,也就是在ActionContext内部记录了那些对象的地址。
上图就是简单理解为什么通过ActionContext可以获得request等对象,其实request和response还是Servlet中我们用的那个对象,只是在ActionContext中被引用了。
从图中也可以看出ActionContext其实就是一个Map集合。
由于requst的生命周期是一次请求,该请求结束后request就会结束,那么ActionContext中的requst自然也就没了,那么ActionContext的生命周期是如何呢?其实每次发出请求时都会创建一个ActionContext,也就是说,ActionContext的生命周期是和request相同的,证明很简单,既然ActionContext是一个Map集合,
那么我们就可以自己向里面添加数据
ActionContext.getContext().put(“test”, “哈哈”);
我们在一个请求中执行上面代码,就是向ActionContext这个Map集合中放一个数据,我们在另一个请求中是否能获得该数据?
ActionContext.getContext().get(“test”);
上面代码是从ActionContext这个Map集合中获得数据,在测试时获得的数据为null,有兴趣的同学可以自己试一试。
从这也就可以看出,两次请求中是不同的ActionContext,
就可以下结论说ActionContext的生命周期是一次请求,也就是同request一样。
从ActionContext中获得解耦域对象
我们知道request,session,application内部都封装了一个域对象,用来存储数据,
requst的域我们上面可以通过获得request对象就可以获得域对象,
那么session和application的域对象怎么获得呢,当然通过requst对象可以获得session对象也可以获得session的域对象,
那么感觉就太麻烦了
在ActionContext中就提供了直接获得域对象的API:
Map
Map
上面的代码就是获得session和application的域对象,可以看出返回值都是一个Map,这个Map就是它们的域对象,
操作这个Map就是操作域对象,
session.put(“key”,“value”);就是向session域中存数据
session.get(“key”);就是从session域中取数据
但是却没有提供直接获得requst域对象的方法,在上面我说过struts2想用ActionContext代替request的域对象,
所以就没有提供获得request域对象的方法。
其实也是在ActionContext这个Map中存放了session和application的Map的引用而已
让我们总结一下:
一》:ActionContext生命周期是一次请求,每次发出请求都会创建一个新的ActionContext,就和request一样,每次创建新的ActionContext时会重新引用那些对象。
二》:而且不只生命周期一样,它本身也具备了request域的功能,可以从后台携带数据到前台,也和request一样
三》:通过ActionContext的子类ServletActionContext可以获得那些对象
四》:通过ActionContext可以直接获得session和application各自的域对象,操作时更方便
五》:最重要一点是:ActionContext本身是一个Map,它存储了很多的对象例如request,response,当然除了这些我们见过的,还有很多我们没见过的对象